惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Help Net Security
博客园 - Franky
GbyAI
GbyAI
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
爱范儿
爱范儿
IT之家
IT之家
酷 壳 – CoolShell
酷 壳 – CoolShell
aimingoo的专栏
aimingoo的专栏
博客园_首页
MongoDB | Blog
MongoDB | Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Recent Announcements
Recent Announcements
Scott Helme
Scott Helme
有赞技术团队
有赞技术团队
M
MIT News - Artificial intelligence
C
CERT Recently Published Vulnerability Notes
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Jina AI
Jina AI
F
Fortinet All Blogs
N
Netflix TechBlog - Medium
L
LangChain Blog
L
LINUX DO - 最新话题
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
H
Hacker News: Front Page
MyScale Blog
MyScale Blog
P
Palo Alto Networks Blog
G
Google Developers Blog
Google DeepMind News
Google DeepMind News
AI
AI
T
Troy Hunt's Blog
Microsoft Azure Blog
Microsoft Azure Blog
阮一峰的网络日志
阮一峰的网络日志
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Vercel News
Vercel News
Microsoft Security Blog
Microsoft Security Blog
罗磊的独立博客
S
Secure Thoughts
大猫的无限游戏
大猫的无限游戏
博客园 - 叶小钗
人人都是产品经理
人人都是产品经理
Blog — PlanetScale
Blog — PlanetScale
博客园 - 司徒正美
Apple Machine Learning Research
Apple Machine Learning Research
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 三生石上(FineUI控件)
S
Security @ Cisco Blogs
Cloudbric
Cloudbric
E
Exploit-DB.com RSS Feed
Attack and Defense Labs
Attack and Defense Labs

博客园 - lhx

C# 非活动窗口截屏 WMI 查找所有物理网卡 [转:IE编程] 如何设置IE8的WebBrowser控件(MSHTML) 的渲染模式 C#实现根据图片的EXIF自动调整图片方向&lt;转&gt; memory released when you minimize the app 自定义控件属性的特性大全&lt;转&gt; 详解自定义托管宿主WCF解决方案开发配置过程(1)【转】 对比两个同类型的List<T>返回差异List<T>集合 - lhx - 博客园 .NET 特性Attribute 如何给DataGridViewComboBoxColumn写事件 将Excel的数据导入DataGridView中[原创] 将DataGridView选中行的值填充到符合命名规则的控件中[原创] Oracle 存储过程 例子~! oracle 存储过程的基本语法(转) 在linux下配置Struts中的Oracle 数据源(原创) 如何给linux添加新硬盘(转) linux 下 mysql-5.0.22. 的安装(转) jQuery Ajax 全解析 (转) tomcat6_jdk1.6_安装配置_开启自动运行,普通用户执行 (转)
用32位应用程序读取64位注册表中的Office key
lhx · 2013-04-04 · via 博客园 - lhx
public class Utility
    {
        #region 32位程序读写64注册表

        static UIntPtr HKEY_CLASSES_ROOT = (UIntPtr)0x80000000;
        static UIntPtr HKEY_CURRENT_USER = (UIntPtr)0x80000001;
        static UIntPtr HKEY_LOCAL_MACHINE = (UIntPtr)0x80000002;
        static UIntPtr HKEY_USERS = (UIntPtr)0x80000003;
        static UIntPtr HKEY_CURRENT_CONFIG = (UIntPtr)0x80000005;

        // 关闭64位(文件系统)的操作转向
        [DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool Wow64DisableWow64FsRedirection(ref IntPtr ptr);
        // 开启64位(文件系统)的操作转向
        [DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool Wow64RevertWow64FsRedirection(IntPtr ptr);

        // 获取操作Key值句柄
        [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern uint RegOpenKeyEx(UIntPtr hKey, string lpSubKey, uint ulOptions, int samDesired, out IntPtr phkResult);
        //关闭注册表转向(禁用特定项的注册表反射)
        [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern long RegDisableReflectionKey(IntPtr hKey);
        //使能注册表转向(开启特定项的注册表反射)
        [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern long RegEnableReflectionKey(IntPtr hKey);
        //获取Key值(即:Key值句柄所标志的Key对象的值)
        [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern int RegQueryValueEx(IntPtr hKey, string lpValueName, int lpReserved,
                                                  out uint lpType, byte[] lpData,
                                                  ref uint lpcbData);

        private static UIntPtr TransferKeyName(string keyName)
        {
            switch (keyName)
            {
                case "HKEY_CLASSES_ROOT":
                    return HKEY_CLASSES_ROOT;
                case "HKEY_CURRENT_USER":
                    return HKEY_CURRENT_USER;
                case "HKEY_LOCAL_MACHINE":
                    return HKEY_LOCAL_MACHINE;
                case "HKEY_USERS":
                    return HKEY_USERS;
                case "HKEY_CURRENT_CONFIG":
                    return HKEY_CURRENT_CONFIG;
            }

            return HKEY_CLASSES_ROOT;
        }

        public static string Get64BitRegistryKey(string parentKeyName, string subKeyName, string keyName)
        {
            int KEY_QUERY_VALUE = (0x0001);
            int KEY_WOW64_64KEY = (0x0100);
            int KEY_ALL_WOW64 = (KEY_QUERY_VALUE | KEY_WOW64_64KEY);

            try
            {
                //将Windows注册表主键名转化成为不带正负号的整形句柄(与平台是32或者64位有关)
                UIntPtr hKey = TransferKeyName(parentKeyName);

                //声明将要获取Key值的句柄
                IntPtr pHKey = IntPtr.Zero;

                //记录读取到的Key值
                //StringBuilder result = new StringBuilder("".PadLeft(1024));
                byte[] ob = new byte[2048];
                uint resultSize = 2048;
                uint lpType = 3;

                //关闭文件系统转向 
                IntPtr oldWOW64State = new IntPtr();
                if (Wow64DisableWow64FsRedirection(ref oldWOW64State))
                {
                    //获得操作Key值的句柄
                    RegOpenKeyEx(hKey, subKeyName, 0, KEY_ALL_WOW64, out pHKey);

                    //关闭注册表转向(禁止特定项的注册表反射)
                    RegDisableReflectionKey(pHKey);

                    //获取访问的Key值
                    RegQueryValueEx(pHKey, keyName, 0, out lpType, ob, ref resultSize);

                    //打开注册表转向(开启特定项的注册表反射)
                    RegEnableReflectionKey(pHKey);
                }

                //打开文件系统转向
                Wow64RevertWow64FsRedirection(oldWOW64State);

                //返回Key值
                string result = DecodeProductKey(ob);
                return result.Trim();
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        public static string DecodeProductKey(byte[] digitalProductId)
        {
            const int keyStartIndex = 0x328;
            const int keyEndIndex = keyStartIndex + 15;

            // Possible alpha-numeric characters in product key.
            char[] digits = new char[]
            {
              'B', 'C', 'D', 'F', 'G', 'H', 'J', 'K', 'M', 'P', 'Q', 'R', 
              'T', 'V', 'W', 'X', 'Y', '2', '3', '4', '6', '7', '8', '9',
            };

            // Length of decoded product key
            const int decodeLength = 29;

            // Length of decoded product key in byte-form.
            // Each byte represents 2 chars.
            const int decodeStringLength = 15;

            // Array of containing the decoded product key.
            char[] decodedChars = new char[decodeLength];

            // Extract byte 52 to 67 inclusive.
            ArrayList hexPid = new ArrayList();
            for (int i = keyStartIndex; i <= keyEndIndex; i++)
            {
                hexPid.Add(digitalProductId[i]);
            }
            for (int i = decodeLength - 1; i >= 0; i--)
            {
                // Every sixth char is a separator.
                if ((i + 1) % 6 == 0)
                {
                    decodedChars[i] = '-';
                }
                else
                {
                    // Do the actual decoding.
                    int digitMapIndex = 0;
                    for (int j = decodeStringLength - 1; j >= 0; j--)
                    {
                        int byteValue = (digitMapIndex << 8) | (byte)hexPid[j];
                        hexPid[j] = (byte)(byteValue / 24);
                        digitMapIndex = byteValue % 24;
                        decodedChars[i] = digits[digitMapIndex];
                    }
                }
            }
            return new string(decodedChars);
        }
        #endregion


调用以office 2010 为例:(当然这个类不仅仅可以用来取office的key)

string key =Utility.Get64BitRegistryKey("HKEY_LOCAL_MACHINE",                            
                        @"
SOFTWARE\Microsoft\Office\14.0\Registration\{91140000-0011-0000-1000-0000000FF1CE}",
                       "DigitalProductID");

lpType 的可能取值

REG_NONE = 0
REG_SZ = 1 ——>字符串
REG_EXPAND_SZ = 2 ——>可展开式字符串
REG_BINARY = 3 ——>Binary数据
REG_DWORD = 4 ——>长整数
REG_DWORD_BIG_ENDIAN = 5 ——>BIG_ENDIAN长整数
REG_MULTI_SZ = 7 ——>多重字符串

我们可能需要根据返回的lpType的类型 和 resultSize 对通过RegQueryValueEx获取到的注册表Key值进行相应转换。