public static UserHook fromCode(string code) { HookParam hp = new HookParam(); if (tryParseCode(code, ref hp)) { return new UserHook(code, hp); } else { return null; } }
public static UserHook fromCode(string code) { HookParam hp = new HookParam(); if (tryParseCode(code, ref hp)) { return(new UserHook(code, hp)); } else { return(null); } }
private static bool tryParseCode(string code, ref HookParam hp) { if (string.IsNullOrWhiteSpace(code)) { return(false); } code = code.Trim().ToUpper(); if (code.StartsWith("/H")) { code = code.Substring(2); } if (code.StartsWith("X")) { return(false); // hardware breakpoints? NO THANK YOU } StringReader sr = new StringReader(code); int cmd = sr.Read(); switch (cmd) { case 'A': hp.length_offset = 1; hp.type |= HookParamType.BIG_ENDIAN; // agth has mixed up descriptions for [A] and [B] break; case 'B': hp.length_offset = 1; break; case 'W': hp.length_offset = 1; hp.type |= HookParamType.USING_UNICODE; break; case 'S': hp.type |= HookParamType.USING_STRING; break; case 'Q': hp.type |= HookParamType.USING_STRING | HookParamType.USING_UNICODE; break; case 'H': hp.type |= HookParamType.PRINT_DWORD; break; case 'L': hp.type |= HookParamType.STRING_LAST_CHAR | HookParamType.USING_UNICODE; break; case 'E': hp.type |= HookParamType.STRING_LAST_CHAR; break; default: return(false); } if (sr.Peek() == 'N') { hp.type |= HookParamType.NO_CONTEXT; sr.Read(); } int hex; if (tryReadHex(sr, true, out hex)) { hp.off = hex; if (sr.Peek() == '*') { sr.Read(); if (!tryReadHex(sr, false, out hex)) { return(false); } hp.type |= HookParamType.DATA_INDIRECT; hp.ind = hex; } if (sr.Peek() == ':') { sr.Read(); if (!tryReadHex(sr, true, out hex)) { return(false); } hp.type |= HookParamType.USING_SPLIT; hp.split = hex; if (sr.Peek() == '*') { sr.Read(); if (!tryReadHex(sr, false, out hex)) { return(false); } hp.type |= HookParamType.SPLIT_INDIRECT; hp.split_ind = hex; } } } if (sr.Read() != '@') { return(false); } if (!tryReadHex(sr, false, out hp.addr)) { return(false); } if (sr.Peek() == ':') { sr.Read(); string module = readUntil(sr, ':'); hp.type |= HookParamType.MODULE_OFFSET; hp.module = calculateHash(module); if (sr.Peek() == ':') { sr.Read(); string func = sr.ReadToEnd(); hp.type |= HookParamType.FUNCTION_OFFSET; hp.function = calculateHash(func); } } else if (sr.Peek() == '!') { sr.Read(); if (!tryReadHex(sr, false, out hp.module)) { return(false); } hp.type |= HookParamType.MODULE_OFFSET; if (sr.Peek() == '!') { sr.Read(); if (!tryReadHex(sr, false, out hp.function)) { return(false); } hp.type |= HookParamType.FUNCTION_OFFSET; } } if (sr.Peek() != -1) { return(false); } return(true); }
protected UserHook(string code, HookParam hookParam) { this.code = code; this.hookParam = hookParam; }
public static extern Int32 TextHookAddHook(ref HookParam p, [MarshalAs(UnmanagedType.LPWStr)] string name);
private static bool tryParseCode(string code, ref HookParam hp) { if (string.IsNullOrWhiteSpace(code)) { return false; } code = code.Trim().ToUpper(); if (code.StartsWith("/H")) { code = code.Substring(2); } if (code.StartsWith("X")) { return false; // hardware breakpoints? NO THANK YOU } StringReader sr = new StringReader(code); int cmd = sr.Read(); switch (cmd) { case 'A': hp.length_offset = 1; hp.type |= HookParamType.BIG_ENDIAN; // agth has mixed up descriptions for [A] and [B] break; case 'B': hp.length_offset = 1; break; case 'W': hp.length_offset = 1; hp.type |= HookParamType.USING_UNICODE; break; case 'S': hp.type |= HookParamType.USING_STRING; break; case 'Q': hp.type |= HookParamType.USING_STRING | HookParamType.USING_UNICODE; break; case 'H': hp.type |= HookParamType.PRINT_DWORD; break; case 'L': hp.type |= HookParamType.STRING_LAST_CHAR | HookParamType.USING_UNICODE; break; case 'E': hp.type |= HookParamType.STRING_LAST_CHAR; break; default: return false; } if (sr.Peek() == 'N') { hp.type |= HookParamType.NO_CONTEXT; sr.Read(); } int hex; if (tryReadHex(sr, true, out hex)) { hp.off = hex; if (sr.Peek() == '*') { sr.Read(); if (!tryReadHex(sr, false, out hex)) { return false; } hp.type |= HookParamType.DATA_INDIRECT; hp.ind = hex; } if (sr.Peek() == ':') { sr.Read(); if (!tryReadHex(sr, true, out hex)) { return false; } hp.type |= HookParamType.USING_SPLIT; hp.split = hex; if (sr.Peek() == '*') { sr.Read(); if (!tryReadHex(sr, false, out hex)) { return false; } hp.type |= HookParamType.SPLIT_INDIRECT; hp.split_ind = hex; } } } if (sr.Read() != '@') { return false; } if (!tryReadHex(sr, false, out hp.addr)) { return false; } if (sr.Peek() == ':') { sr.Read(); string module = readUntil(sr, ':'); hp.type |= HookParamType.MODULE_OFFSET; hp.module = calculateHash(module); if (sr.Peek() == ':') { sr.Read(); string func = sr.ReadToEnd(); hp.type |= HookParamType.FUNCTION_OFFSET; hp.function = calculateHash(func); } } else if (sr.Peek() == '!') { sr.Read(); if (!tryReadHex(sr, false, out hp.module)) { return false; } hp.type |= HookParamType.MODULE_OFFSET; if (sr.Peek() == '!') { sr.Read(); if (!tryReadHex(sr, false, out hp.function)) { return false; } hp.type |= HookParamType.FUNCTION_OFFSET; } } if (sr.Peek() != -1) { return false; } return true; }