|
1 | 1 | using System;
|
| 2 | +using System.Linq; |
2 | 3 | using ntregsharp;
|
| 4 | +using System.Collections.Generic; |
| 5 | +using System.Text; |
3 | 6 |
|
4 | 7 | namespace ch11_reading_offline_hives
|
5 | 8 | {
|
6 | 9 | class MainClass
|
7 | 10 | {
|
8 | 11 | public static void Main (string[] args)
|
9 | 12 | {
|
10 |
| - RegistryHive hive = new RegistryHive (args [0]); |
11 |
| - |
12 |
| - Console.WriteLine("The rootkey's name is " + hive.RootKey.Name); |
| 13 | + RegistryHive systemHive = new RegistryHive (args [0]); |
| 14 | + byte[] bootKey = GetBootKey (systemHive); |
| 15 | + |
| 16 | + Console.WriteLine ("Boot key: " + BitConverter.ToString (bootKey)); |
| 17 | + } |
| 18 | + |
| 19 | + static byte[] GetBootKey(RegistryHive hive){ |
| 20 | + ValueKey controlSet = GetValueKey (hive, "Select|Default"); |
| 21 | + int cs = BitConverter.ToInt32 (controlSet.Data, 0); |
| 22 | + |
| 23 | + StringBuilder scrambledKey = new StringBuilder (); |
| 24 | + foreach (string key in new string[] {"JD", "Skew1", "GBG", "Data"}) { |
| 25 | + NodeKey nk = GetNodeKey (hive, "ControlSet00" + cs + "|Control|Lsa|" + key); |
| 26 | + |
| 27 | + for (int i = 0; i < nk.ClassnameLength && i < 8; i++) |
| 28 | + scrambledKey.Append ((char)nk.ClassnameData [i*2]); |
| 29 | + } |
| 30 | + |
| 31 | + byte[] skey = StringToByteArray (scrambledKey.ToString ()); |
| 32 | + byte[] descramble = new byte[] { 0x8, 0x5, 0x4, 0x2, 0xb, 0x9, 0xd, 0x3, |
| 33 | + 0x0, 0x6, 0x1, 0xc, 0xe, 0xa, 0xf, 0x7 }; |
| 34 | + |
| 35 | + byte[] bootkey = new byte[16]; |
| 36 | + for (int i = 0; i < bootkey.Length; i++) |
| 37 | + bootkey[i] = skey [descramble [i]]; |
| 38 | + |
| 39 | + return bootkey; |
| 40 | + } |
| 41 | + |
| 42 | + static byte[] StringToByteArray(string hex) { |
| 43 | + return Enumerable.Range(0, hex.Length) |
| 44 | + .Where(x => x % 2 == 0) |
| 45 | + .Select(x => Convert.ToByte(hex.Substring(x, 2), 16)) |
| 46 | + .ToArray(); |
| 47 | + } |
| 48 | + |
| 49 | + static NodeKey GetNodeKey(RegistryHive hive, string path){ |
| 50 | + |
| 51 | + NodeKey node = null; |
| 52 | + string[] paths = path.Split ('|'); |
| 53 | + |
| 54 | + for (int i = 0;i < paths.Length; i++) { |
| 55 | + |
| 56 | + if (node == null) |
| 57 | + node = hive.RootKey; |
| 58 | + |
| 59 | + foreach (NodeKey child in node.ChildNodes) { |
| 60 | + if (child.Name == paths [i]) { |
| 61 | + node = child; |
| 62 | + break; |
| 63 | + } |
| 64 | + } |
| 65 | + } |
| 66 | + |
| 67 | + return node; |
| 68 | + } |
| 69 | + |
| 70 | + static ValueKey GetValueKey(RegistryHive hive, string path) { |
| 71 | + |
| 72 | + string keyname = path.Split ('|').Last (); |
| 73 | + NodeKey node = GetNodeKey (hive, path); |
| 74 | + |
| 75 | + return node.ChildValues.SingleOrDefault (v => v.Name == keyname); |
13 | 76 | }
|
14 | 77 | }
|
15 | 78 | }
|
0 commit comments