• Fuentes

 #392250  por adwind
 
Con esta clase podemos accesar al registro de windows sin necesidad de usar el cmd.
Se usa reflexión para accesar a las clases prohibidas por java XD para listar las entradas.

Este código no es mio, pero si corregi algunas cosas. No listaba correctamente las entradas.
Ahora funcina bien.


PD: En el main incluyo una rutina para obtener las contraseñas que guarda el Internet Download Manager XD
convino esta clase + cmd.
Código: Seleccionar todo
package extra;
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
//~--- JDK imports ------------------------------------------------------------
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.prefs.Preferences;

/*Modificado por adwind
 el 04-08-2012
 Tenia errores al listar las subkeys
 */
public class RegistryUtils {

    // inspired by
    // http://javabyexample.wisdomplug.com/java-concepts/34-core-java/62-java-registry-wrapper.html
    // http://www.snipcode.org/java/1-java/23-java-class-for-accessing-reading-and-writing-from-windows-registry.html
    // http://snipplr.com/view/6620/accessing-windows-registry-in-java/
    public static final int HKEY_CURRENT_USER = 0x80000001;
    public static final int HKEY_LOCAL_MACHINE = 0x80000002;
    private static final int KEY_ALL_ACCESS = 0xf003f;
    private static final int KEY_WRITE = 0x20006;
    private static final int KEY_READ = 0x20019;
    public static final int REG_ACCESSDENIED = 5;
    public static final int REG_NOTFOUND = 2;
    public static final int REG_SUCCESS = 0;
    private static Method regCloseKey = null;
    private static Method regCreateKeyEx = null;
    private static Method regDeleteKey = null;
    private static Method regDeleteValue = null;
    private static Method regEnumKeyEx = null;
    private static Method regEnumValue = null;
    private static Method regOpenKey = null;
    private static Method regQueryInfoKey = null;
    private static Method regQueryValueEx = null;
    private static Method regSetValueEx = null;
    private static Preferences userRoot = Preferences.userRoot();
    private static Class<? extends Preferences> userClass = userRoot.getClass();
    private static Preferences systemRoot = Preferences.systemRoot();
    //WindowsRegOpenKey
//    private static char[] a = new char[]{0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x67, 0x4f, 0x70, 0x65, 0x6e, 0x4b, 0x65, 0x79};
    //WindowsRegCloseKey
//    private static char[] b = new char[]{0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x67, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x4b, 0x65, 0x79};
    static {
        try {
            regOpenKey = userClass.getDeclaredMethod("WindowsRegOpenKey", new Class[]{int.class, byte[].class,
                        int.class});
            regOpenKey.setAccessible(true);
            regCloseKey = userClass.getDeclaredMethod("WindowsRegCloseKey", new Class[]{int.class});
            regCloseKey.setAccessible(true);
            regQueryValueEx = userClass.getDeclaredMethod("WindowsRegQueryValueEx", new Class[]{int.class,
                        byte[].class});
            regQueryValueEx.setAccessible(true);
            regEnumValue = userClass.getDeclaredMethod("WindowsRegEnumValue", new Class[]{int.class, int.class,
                        int.class});
            regEnumValue.setAccessible(true);
            regQueryInfoKey = userClass.getDeclaredMethod("WindowsRegQueryInfoKey1", new Class[]{int.class});
            regQueryInfoKey.setAccessible(true);
            regEnumKeyEx = userClass.getDeclaredMethod("WindowsRegEnumKeyEx", new Class[]{int.class, int.class,
                        int.class});
            regEnumKeyEx.setAccessible(true);
            regCreateKeyEx = userClass.getDeclaredMethod("WindowsRegCreateKeyEx", new Class[]{int.class,
                        byte[].class});
            regCreateKeyEx.setAccessible(true);
            regSetValueEx = userClass.getDeclaredMethod("WindowsRegSetValueEx", new Class[]{int.class, byte[].class,
                        byte[].class});
            regSetValueEx.setAccessible(true);
            regDeleteValue = userClass.getDeclaredMethod("WindowsRegDeleteValue", new Class[]{int.class,
                        byte[].class});
            regDeleteValue.setAccessible(true);
            regDeleteKey = userClass.getDeclaredMethod("WindowsRegDeleteKey", new Class[]{int.class, byte[].class});
            regDeleteKey.setAccessible(true);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Read a value from key and value name
     * @param hkey   HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
     * @param key
     * @param valueName
     * @return the value
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     */
    public static String readString(int hkey, String key, String valueName)
            throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
        switch (hkey) {
            case HKEY_LOCAL_MACHINE:
                return readString(systemRoot, hkey, key, valueName);
            case HKEY_CURRENT_USER:
                return readString(userRoot, hkey, key, valueName);
            default:
                throw new IllegalArgumentException("hkey=" + hkey);
        }

    }

    /**
     * Read value(s) and value name(s) form given key
     * @param hkey  HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
     * @param key
     * @return the value name(s) plus the value(s)
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     */
    public static Map<String, String> readStringValues(int hkey, String key)
            throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
                switch (hkey) {
            case HKEY_LOCAL_MACHINE:
                return readStringValues(systemRoot, hkey, key);
            case HKEY_CURRENT_USER:
                return readStringValues(userRoot, hkey, key);
            default:
              throw new IllegalArgumentException("hkey=" + hkey);
        }   
    }

    /**
     * Read the value name(s) from a given key
     * @param hkey  HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
     * @param key
     * @return the value name(s)
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     */
    public static List<String> readStringSubKeys(int hkey, String key)
            throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
        switch (hkey) {
            case HKEY_LOCAL_MACHINE:
                return readStringSubKeys(systemRoot, hkey, key);
            case HKEY_CURRENT_USER:
                return readStringSubKeys(userRoot, hkey, key);
            default:
                throw new IllegalArgumentException("hkey=" + hkey);
        }
    }

    /**
     * Create a key
     * @param hkey  HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
     * @param key
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     */
    public static void createKey(int hkey, String key)
            throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
        int[] ret = null;
        switch (hkey) {
            case HKEY_LOCAL_MACHINE:
                ret = createKey(systemRoot, hkey, key);
                regCloseKey.invoke(systemRoot, new Object[]{new Integer(ret[0])});
                break;
            case HKEY_CURRENT_USER:
                ret = createKey(userRoot, hkey, key);
                regCloseKey.invoke(userRoot, new Object[]{new Integer(ret[0])});
                break;
            default:
                throw new IllegalArgumentException("hkey=" + hkey);
        }
        if (ret[1] != REG_SUCCESS) {
            throw new IllegalArgumentException("rc=" + ret[1] + "  key=" + key);
        }
    }

    /**
     * Write a value in a given key/value name
     * @param hkey
     * @param key
     * @param valueName
     * @param value
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     */
    public static void writeStringValue(int hkey, String key, String valueName, String value)
            throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
        switch (hkey) {
            case HKEY_LOCAL_MACHINE:
                writeStringValue(systemRoot, hkey, key, valueName, value);
                break;
            case HKEY_CURRENT_USER:
                writeStringValue(userRoot, hkey, key, valueName, value);
                break;
            default:
                throw new IllegalArgumentException("hkey=" + hkey);
        }
    }

    /**
     * Delete a given key
     * @param hkey
     * @param key
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     */
    public static void deleteKey(int hkey, String key)
            throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
        int rc = -1;
        switch (hkey) {
            case HKEY_LOCAL_MACHINE:
              rc = deleteKey(systemRoot, hkey, key);
                break;
            case HKEY_CURRENT_USER:
                rc = deleteKey(userRoot, hkey, key);
                break;
            default:
                throw new IllegalArgumentException("hkey=" + hkey);
        }

        if (rc != REG_SUCCESS) {
            throw new IllegalArgumentException("rc=" + rc + "  key=" + key);
        }
    }

    /**
     * delete a value from a given key/value name
     * @param hkey
     * @param key
     * @param value
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     */
    public static void deleteValue(int hkey, String key, String value)
            throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
        int rc = -1;

        
                switch (hkey) {
            case HKEY_LOCAL_MACHINE:
             rc = deleteValue(systemRoot, hkey, key, value);
                break;
            case HKEY_CURRENT_USER:
                 rc = deleteValue(userRoot, hkey, key, value);
                break;
            default:
                throw new IllegalArgumentException("hkey=" + hkey);
        }
//        if (rc != REG_SUCCESS) {
//            throw new IllegalArgumentException("rc=" + rc + "  key=" + key + "  value=" + value);
//        }
    }

    // =====================
    private static int deleteValue(Preferences root, int hkey, String key, String value)
            throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
        int[] handles = (int[]) regOpenKey.invoke(root, new Object[]{new Integer(hkey), toCstr(key),
                    new Integer(KEY_ALL_ACCESS)});

        if (handles[1] != REG_SUCCESS) {
            return handles[1];    // can be REG_NOTFOUND, REG_ACCESSDENIED
        }

        int rc = ((Integer) regDeleteValue.invoke(root,
                new Object[]{new Integer(handles[0]), toCstr(value)})).intValue();

        regCloseKey.invoke(root, new Object[]{new Integer(handles[0])});

        return rc;
    }

    private static int deleteKey(Preferences root, int hkey, String key)
            throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
        int rc = ((Integer) regDeleteKey.invoke(root, new Object[]{new Integer(hkey), toCstr(key)})).intValue();

        return rc;    // can REG_NOTFOUND, REG_ACCESSDENIED, REG_SUCCESS
    }

    private static String readString(Preferences root, int hkey, String key, String value)
            throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
        int[] handles = (int[]) regOpenKey.invoke(root, new Object[]{new Integer(hkey), toCstr(key),
                    new Integer(KEY_READ)});

        if (handles[1] != REG_SUCCESS) {
            return null;
        }
        byte[] valb = (byte[]) regQueryValueEx.invoke(root, new Object[]{new Integer(handles[0]), toCstr(value)});
        regCloseKey.invoke(root, new Object[]{new Integer(handles[0])});

        return ((valb != null)
                ? new String(valb).trim()
                : null);
    }

    private static Map<String, String> readStringValues(Preferences root, int hkey, String key)
            throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
        HashMap<String, String> results = new HashMap<String, String>();
        int[] handles = (int[]) regOpenKey.invoke(root, new Object[]{new Integer(hkey), toCstr(key),
                    new Integer(KEY_READ)});

        if (handles[1] != REG_SUCCESS) {
            return null;
        }

        int[] info = (int[]) regQueryInfoKey.invoke(root, new Object[]{new Integer(handles[0])});
        int count = info[2];    // count
        int maxlen = info[4]; 
                for(int ii: info) {
                    System.out.println(ii);
                }
//        System.out.println(maxlen);// value length max
//        System.out.println(count);
        for (int index = 0; index < count; index++) {

            byte[] name=%28byte%26%2391%3B%26%2393%3B%29 regEnumValue.invoke(root, new Object[]{new Integer(handles[0]), new Integer(index),
                        new Integer(maxlen + 1)});
  
            String value = readString(hkey, key, new String(name));

            results.put(new String(name).trim(), value);
        }

        regCloseKey.invoke(root, new Object[]{new Integer(handles[0])});

        return results;
    }

    private static List<String> readStringSubKeys(Preferences root, int hkey, String key)
            throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
        List<String> results = new ArrayList<String>();
        int[] handles = (int[]) regOpenKey.invoke(root, new Object[]{new Integer(hkey), toCstr(key),
                    new Integer(KEY_READ)});

//        System.out.println(handles[1]);
        if (handles[1] != REG_SUCCESS) {
            return null;
        }

        int[] info = (int[]) regQueryInfoKey.invoke(root, new Object[]{new Integer(handles[0])});
        for(int ii: info) {
                    System.out.println(ii);
                }
        int count = info[0];    // count
        int maxlen = info[3];    // value length max
        for (int index = 0; index < count; index++) {
            byte[] name=%28byte%26%2391%3B%26%2393%3B%29 regEnumKeyEx.invoke(root, new Object[]{new Integer(handles[0]), new Integer(index),
                        new Integer(maxlen + 1)});
            results.add(new String(name).trim());
        }
        regCloseKey.invoke(root, new Object[]{new Integer(handles[0])});

        return results;
    }

    private static int[] createKey(Preferences root, int hkey, String key)
            throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
        return (int[]) regCreateKeyEx.invoke(root, new Object[]{new Integer(hkey), toCstr(key)});
    }

    private static void writeStringValue(Preferences root, int hkey, String key, String valueName, String value)
            throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
        int[] handles = (int[]) regOpenKey.invoke(root, new Object[]{new Integer(hkey), toCstr(key),
                    new Integer(KEY_WRITE)});
        
          if (handles[1] != REG_SUCCESS) {
              throw new IllegalArgumentException("rc=" +handles[1] + "  key=" + key + "  value=" + value);
        }
        regSetValueEx.invoke(root, new Object[]{new Integer(handles[0]), toCstr(valueName), toCstr(value)});
        regCloseKey.invoke(root, new Object[]{new Integer(handles[0])});
        
    }

    // utility
    private static byte[] toCstr(String str) {
        byte[] result = new byte[str.length() + 1];
        for (int i = 0; i < str.length(); i++) 
        {
            result[i] = (byte) str.charAt(i);
        }
        result[str.length()] = 0;
        return result;
    }
 
        public static List<String> listaSubclaves(String t){
        List<String> lista=new ArrayList<String>();
        
                try {
            Process p = Runtime.getRuntime().exec(new String[]{"reg", "query", t});
                        p.waitFor();
                        BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream(), "UTF-8"));
                        while(br.ready()){
                        String url=br.readLine();
                        if(url.isEmpty()) continue;
                        System.out.println(url);
//                        System.out.println(url);
//                        System.out.println(url);
//                            System.out.println(url);
//                        String h[]=url.split(Pattern.quote("\\"));
//                            System.out.println(h[4]);
//                        lista.add(h[4]);
                        }
               
                        
                        
                        p.destroy();
                      
        } catch (Exception ex) {
           
        }
       return lista;
    }
    
    public static void main(String[] args) {
        listaSubclaves("HKCU\\Software\\DownloadManager\\Passwords");
        
        try {
           List<String> l= readStringSubKeys(RegistryUtils.HKEY_CURRENT_USER, "Software\\DownloadManager\\Passwords");
           String a[]=l.toArray(new String[]{});
           
           for(String aa:a){
               System.out.println("****************************");
               Process p=Runtime.getRuntime().exec(new String[]{"reg","query","HKCU\\Software\\DownloadManager\\Passwords\\"+aa,"/v", "User"});
                System.out.println(aa);
                p.waitFor();
                BufferedReader br=new BufferedReader(new InputStreamReader(p.getInputStream(),"UTF-8"));
                
                
                br.readLine();
                br.readLine();
                String tmp=br.readLine();
                String todo[]=tmp.split("REG_NONE");
                System.out.println(todo[0].trim()+":"+fromHexString(todo[1].trim(),0));
                p.destroy();
                p=Runtime.getRuntime().exec(new String[]{"reg","query","HKCU\\Software\\DownloadManager\\Passwords\\"+aa,"/v", "EncPassword"});
p.waitFor();
                br=new BufferedReader(new InputStreamReader(p.getInputStream(),"UTF-8"));
                      
                
                br.readLine();
                br.readLine();
                tmp=br.readLine();
                todo=tmp.split("REG_NONE");
                System.out.println(todo[0].trim()+":"+fromHexString(todo[1].trim(),0xf));
                p.destroy();          
                
           }
        } catch (Exception ex) {
//            Logger.getLogger(RegistryUtils.class.getName()).log(Level.SEVERE, null, ex);
        }
        
    }
    
    public static String fromHexString(String hex, int exp) {
    StringBuilder str = new StringBuilder();
    for (int i = 0; i < hex.length(); i+=2) {
        
        str.append((char) (Integer.parseInt(hex.substring(i, i + 2), 16)^exp));
    }
    return str.toString();
}
    

    

}