public void Tokenize(String s, AStringArray tokens) { String t; var last = 0; var inQuote = false; for (var i = 0; i < s.Length; i++) { if (!UArrayUtils.InArray(s[i], '"', '[', ']', '+', '-', '*')) { continue; } if (s[i] == '"') { if (!inQuote) { last = i + 1; } inQuote = !inQuote; } if (inQuote) { continue; } t = AStringUtils.Copy(s, last, i - last).Trim(); if (t != "") { tokens.SetLength(tokens.Length + 1); tokens.Last = t; } //store separator char as well, unless it's " if (s[i] != '"') { tokens.SetLength(tokens.Length + 1); tokens.Last = s[i].ToString(); } last = i + 1; } //last part t = AStringUtils.Copy(s, last, s.Length).Trim(); if (t == "") { return; } tokens.SetLength(tokens.Length + 1); tokens.Last = t; }
public Boolean Rewrite(ref String token) { if (token.Length == 0) { return(false); //empty string } var tokens = new AStringArray(); var quoteChar = '\0'; tokens.SetLength(0); String temp; /* 5.4: special pointer notation case */ if (token.Length > 4 && token.StartsWith("[[") && token.EndsWith("]]")) { //looks like a pointer in a address specifier (idiot user detected...) temp = "[" + AStringUtils.IntToHex(SymbolHandler.GetAddressFromName(AStringUtils.Copy(token, 2, token.Length - 4), true, out var haserror), 8) + ']'; if (!haserror) { token = temp; } else { throw new Exception("Invalid"); } } /* 5.4 ^^^ */ temp = ""; var i = 0; var inQuote = false; while (i < token.Length) { if (UArrayUtils.InArray(token[i], '\'', '"')) { if (inQuote) { if (token[i] == quoteChar) { inQuote = false; } } else { //start of a quote quoteChar = token[i]; inQuote = true; } } if (!inQuote) { if (UArrayUtils.InArray(token[i], '[', ']', '+', '-', ' ')) //6.8.4 (added ' ' for FAR, LONG, SHORT) { if (temp != "") { tokens.SetLength(tokens.Length + 1); tokens.Last = temp; temp = ""; } if (tokens.Length > 0 && UArrayUtils.InArray(token[i], '+', '-') && (tokens[tokens.Length - 1] == " ")) //relative offset ' +xxx' { temp += token[i]; i++; continue; } tokens.SetLength(tokens.Length + 1); tokens[tokens.Length - 1] = token[i].ToString(); i++; continue; } } temp += token[i]; i++; } if (temp != "") { tokens.SetLength(tokens.Length + 1); tokens[tokens.Length - 1] = temp; temp = ""; } for (i = 0; i < tokens.Length; i++) { if (tokens[i].Length >= 1 && !UArrayUtils.InArray(tokens[i][0], '[', ']', '+', '-', '*', ' ')) //3/16/2011: 11:15 (replaced or with and) { AStringUtils.Val("0x" + tokens[i], out Int64 _, out var err); if (err != 0 && GetReg(tokens[i], false) == -1) //not a hexadecimal value and not a register { temp = AStringUtils.IntToHex(SymbolHandler.GetAddressFromName(tokens[i], true, out var hasError), 8); if (!hasError) { tokens[i] = temp; //can be rewritten as a hexadecimal } else { if (tokens.Length > 0 && UArrayUtils.InArray(token[i], '+', '-') && tokens[tokens.Length - 1] == " ") //relative offset ' +xxx' { temp += token[i]; i++; continue; } var j = AStringUtils.Pos("*", tokens[i]); if (j != -1) //getreg failed, but could be it's the 'other' one { if (tokens[i].Length > j && (UArrayUtils.InArray(AStringUtils.Copy(tokens[i], j + 1, 1)[0], '2', '4', '8'))) { continue; //reg*2 / *3, /*4 } } if (i < tokens.Length - 1) { //perhaps it can be concatenated with the next one if (tokens[i + 1].Length > 0 && !UArrayUtils.InArray(tokens[i + 1][0], '\'', '"', '[', ']', '(', ')', ' ')) //not an invalid token char { tokens[i + 1] = tokens[i] + tokens[i + 1]; tokens[i] = ""; } } } } } } //do some calculations //check multiply first for (i = 1; i <= tokens.Length - 2; i++) { if (tokens[i] == "*") { AStringUtils.Val("0x" + tokens[i - 1], out Int64 a, out var err); AStringUtils.Val("0x" + tokens[i + 1], out Int64 b, out var err2); if (err == 0 && err2 == 0) { a *= b; tokens[i - 1] = AStringUtils.IntToHex(a, 8); tokens[i] = ""; tokens[i + 1] = ""; i -= 2; } } } for (i = 1; i <= tokens.Length - 2; i++) { //get the value of the token before and after this token AStringUtils.Val("0x" + tokens[i - 1], out Int64 a, out var err); AStringUtils.Val("0x" + tokens[i + 1], out Int64 b, out var err2); //if no error, check if this token is a mathemetical value if (err == 0 && err2 == 0) { switch (tokens[i][0]) { case '+': { a += b; tokens[i - 1] = AStringUtils.IntToHex(a, 8); tokens.Remove(i, 2); i -= 2; } break; case '-': { a -= b; tokens[i - 1] = AStringUtils.IntToHex(a, 8); tokens.Remove(i, 2); i -= 2; } break; } } else { if ((err2 == 0) && (tokens[i] != "") && (tokens[i][0] == '-') && (tokens[i - 1] != "#")) //before is not a valid value, but after it is. and this is a - (so -value) (don't mess with #-10000) { tokens[i] = "+"; tokens[i + 1] = AStringUtils.IntToHex(-b, 8); } } } token = ""; //remove useless tokens for (i = 0; i < tokens.Length; i++) { token += tokens[i]; } tokens.SetLength(0); return(true); }
public Boolean Tokenize(String opCode, AStringArray tokens) { var quoteChar = '\0'; tokens.SetLength(0); if (opCode.Length > 0) { opCode = opCode.TrimEnd(' ', ','); } var last = 0; var quoted = false; int i, j; for (i = 0; i <= opCode.Length; i++) { //check if this is a quote char if (i < opCode.Length && (opCode[i] == '\'' || opCode[i] == '"')) { if (quoted) //check if it's the end quote { if (opCode[i] == quoteChar) { quoted = false; } } else { quoted = true; quoteChar = opCode[i]; } } //check if we encounter a token seperator. (space or , ) //but only check when it's not inside a quoted string if ((i == opCode.Length) || ((!quoted) && ((opCode[i] == ' ') || (opCode[i] == ',')))) { tokens.SetLength(tokens.Length + 1); if (i == opCode.Length) { j = i - last + 1; } else { j = i - last; } tokens.Last = AStringUtils.Copy(opCode, last, j); if (j > 0 && (tokens.Last[0] != '$') && (j < 7 || (AStringUtils.Pos("KERNEL_", tokens.Last, true) == -1))) //only uppercase if it's not kernel_ { //don't uppercase empty strings, kernel_ strings or strings starting with $ if (tokens.Last.Length > 2) { if (!UArrayUtils.InArray(tokens.Last[0], '\'', '"')) //if not a quoted string then make it uppercase { tokens.Last = tokens.Last.ToUpper(); } } else { tokens.Last = tokens.Last.ToUpper(); } } //6.1: Optimized this lookup. Instead of a 18 compares a full string lookup on each token it now only compares up to 4 times var t = tokens.Last; var isPartial = false; if (t.Length >= 3) //3 characters are good enough to get the general idea, then do a string compare to verify { switch (t[0]) { case 'B': //BYTE, BYTE PTR { if (t[1] == 'Y' && t[2] == 'T') //could be BYTE { isPartial = t == "BYTE" || t == "BYTE PTR"; } } break; case 'D': //DQWORD, DWORD, DQWORD PTR, DWORD PTR { switch (t[1]) { case 'Q': //DQWORD or DQWORD PTR { if (t[2] == 'W') { isPartial = t == "DQWORD" || t == "DQWORD PTR"; } } break; case 'W': //DWORD or DWORD PTR { if (t[2] == 'O') { isPartial = t == "DWORD" || t == "DWORD PTR"; } } break; } } break; case 'F': //FAR { if (t[1] == 'A' && t[2] == 'R') { isPartial = t == "FAR"; } } break; case 'L': //LONG { if (t[1] == 'O' && t[2] == 'N') { isPartial = t == "LONG"; } } break; case 'Q': //QWORD, QWORD PTR { if (t[1] == 'W' && t[2] == 'O') //could be QWORD { isPartial = t == "QWORD" || t == "QWORD PTR"; } } break; case 'S': //SHORT { if (t[1] == 'H' && t[2] == 'O') { isPartial = (t == "SHORT"); } } break; case 'T': //TBYTE, TWORD, TBYTE PTR, TWORD PTR, { switch (t[1]) { case 'B': //TBYTE or TBYTE PTR { if (t[2] == 'Y') { isPartial = (t == "TBYTE") || (t == "TBYTE PTR"); } } break; case 'W': //TWORD or TWORD PTR { if (t[2] == 'O') { isPartial = (t == "TWORD") || (t == "TWORD PTR"); } } break; } } break; case 'W': //WORD, WORD PTR { if (t[1] == 'O' && t[3] == 'R') //could be WORD { isPartial = t == "WORD" || t == "WORD PTR"; } } break; } } if (isPartial) { tokens.SetLength(tokens.Length - 1); } else { last = i + 1; if (tokens.Length > 1) { var lastElem = tokens.Last; Rewrite(ref lastElem); //Rewrite tokens.Last = lastElem; } } } } //remove useless tokens i = 0; while (i < tokens.Length) { if (tokens[i] == "" || tokens[i] == " " || tokens[i] == ",") { for (j = i; j < tokens.Length - 1; j++) { tokens[j] = tokens[j + 1]; } tokens.SetLength(tokens.Length - 1); continue; } i++; } return(true); }
public static void ConvertStringToBytes(String aobStr, Boolean hex, ATByteArray bytes) { // vars int i, j, k; String temp; // wildcard for AoBScan and AoBAssert.Bigger than $FF is ok. var wildCard = (UInt16)0xf521; var wildcardChars = new[] { 'x', 'X', '?', '*' }; // size check bytes.SetLength(0); if (aobStr.Length == 0) { return; } aobStr = aobStr.Trim(); if ((Pos("-", aobStr) != -1) || (Pos(" ", aobStr) != -1) || (Pos(",", aobStr) != -1)) { /*syntax is : (1)xx-xx-xx (2)or xx xx xx (3)or xx,xx,xx*/ j = 0; k = 0; aobStr += ' '; for (i = 0; i < aobStr.Length; i++) { if (UArrayUtils.InArray(aobStr[i], ' ', '-', ',')) { temp = Copy(aobStr, j, i - j); j = i + 1; bytes.SetLength(k + 1); if (UStringUtils.IndexOfAny(temp, wildcardChars) == -1) { switch (hex) { case true: bytes[k] = (UInt16)StrToInt("0x" + temp); break; case false: bytes[k] = (UInt16)StrToInt(temp); break; } } else { bytes[k] = wildCard; } k += 1; } } } else { /*syntax is: xxxxxx*/ k = 0; j = 1; for (i = 1; i <= aobStr.Length; i++) { if ((i % 2) != 0) { continue; } temp = Copy(aobStr, j, i - j + 1); j = i + 1; bytes.SetLength(k + 1); if (UStringUtils.IndexOfAny(temp, wildcardChars) == -1) { bytes[k] = (UInt16)StrToInt("0x" + temp); } else { bytes[k] = wildCard; } k += 1; } } }
public static int CopyMemory(AByteArray dest, AByteArray src, int size) { return(UArrayUtils.CopyMemory(dest.Buffer, 0, src.Buffer, 0, size)); }
public static int CopyMemory(UBytePtr dest, UBytePtr src, int size) { return(UArrayUtils.CopyMemory(dest.ToIntPtr(), 0, src.ToIntPtr(), 0, size)); }
public UIntPtr GetAddressFromName(String name, Boolean waitForSymbols, out Boolean hasError) { var result = UIntPtr.Zero; const int calcAddition = 0; const int calcSubstraction = 1; int offset; int i, j; Boolean error; var tokens = new AStringArray(); string mathstring; var hasMultiplication = false; var nextoperation = 0; int regnr; name = name.Trim(); var hasPointer = false; hasError = false; offset = 0; AStringUtils.Val("0x" + name, out result, out i); if (i == 0) { return(result); //it's a valid hexadecimal string } if (AStringUtils.Copy(name, 1, 2).ToLower() == "0x") { AStringUtils.Val(name, out result, out i); if (i == 0) { return(result); } } //not a hexadecimal string Tokenize(name, tokens); //first check the most basic thing if (tokens.Length == 0) { hasError = true; return(result); } /*--if it starts with a * or ends with *, - or +, then it's a bad formula--*/ if (tokens[0][0] == '*' || UArrayUtils.InArray(tokens[tokens.Length - 1][0], '*', '+', '-')) { hasError = true; return(result); } /*----convert the tokens into hexadecimal values--------*/ lock (SymbolLock) { //try {tokens format ex.:=array('islandtribe.exe','+','AB754')} for (i = 0; i < tokens.Length; i++) { if (!UArrayUtils.InArray(tokens[i][0], '[', ']', '+', '-', '*')) { AStringUtils.Val("0x" + tokens[i], out result, out j); if (j <= 0) { continue; // hexadecimal value } //not a hexadecimal value var mi = Process.ModuleFactory.FetchModule(tokens[i]); if (mi != null) { tokens[i] = AStringUtils.IntToHex(mi.BaseAddress.ToUIntPtr(), 8); continue; } var mib = _moduleList.FindBaseAddress(tokens[i]); if (mib != IntPtr.Zero) { tokens[i] = AStringUtils.IntToHex(mib.ToUIntPtr(), 8); continue; } regnr = -1;// getreg(tokens[i].ToUpper(), false); // todo fill this in? if (regnr != -1) { #region NO CONTEXT // //if (context<>nil) and (context^.{$ifdef cpu64}Rip{$else}Eip{$endif}<>0) then // if (context != nil) // { // //get the register value, and because this is an address specifier, use the full 32-bits // switch (regnr) // { // // 0: tokens[i]:=inttohex(context^.{$ifdef cpu64}rax{$else}eax{$endif},8); // // 1: tokens[i]:=inttohex(context^.{$ifdef cpu64}rcx{$else}ecx{$endif},8); // // 2: tokens[i]:=inttohex(context^.{$ifdef cpu64}rdx{$else}edx{$endif},8); // // 3: tokens[i]:=inttohex(context^.{$ifdef cpu64}rbx{$else}ebx{$endif},8); // // 4: tokens[i]:=inttohex(context^.{$ifdef cpu64}rsp{$else}esp{$endif},8); // // 5: tokens[i]:=inttohex(context^.{$ifdef cpu64}rbp{$else}ebp{$endif},8); // // 6: tokens[i]:=inttohex(context^.{$ifdef cpu64}rsi{$else}esi{$endif},8); // // 7: tokens[i]:=inttohex(context^.{$ifdef cpu64}rdi{$else}edi{$endif},8); // case 0: tokens[i] = inttohex(context->eax, 8); break; // case 1: tokens[i] = inttohex(context->ecx, 8); break; // case 2: tokens[i] = inttohex(context->edx, 8); break; // case 3: tokens[i] = inttohex(context->ebx, 8); break; // case 4: tokens[i] = inttohex(context->esp, 8); break; // case 5: tokens[i] = inttohex(context->ebp, 8); break; // case 6: tokens[i] = inttohex(context->esi, 8); break; // case 7: tokens[i] = inttohex(context->edi, 8); break; // //{$ifdef cpu64} // case 8: tokens[i] = inttohex(context->r8, 8); break; // case 9: tokens[i] = inttohex(context->r9, 8); break; // case 10: tokens[i] = inttohex(context->r10, 8); break; // case 11: tokens[i] = inttohex(context->r11, 8); break; // case 12: tokens[i] = inttohex(context->r12, 8); break; // case 13: tokens[i] = inttohex(context->r13, 8); break; // case 14: tokens[i] = inttohex(context->r14, 8); break; // case 15: tokens[i] = inttohex(context->r15, 8); break; // //{$endif} // } // // continue_; //handled // } // //not handled, but since it's a register, quit now #endregion } else { /*-----------------user defined symbol-------------------*/ result = GetUserDefinedSymbolByName(tokens[i]); if (result != UIntPtr.Zero) { tokens[i] = AStringUtils.IntToHex(result, 8); continue; } /*----------------Process Module Symbol----------------*/ if (waitForSymbols) { WaitForSymbolsLoaded(); } result = GetAddressFromSymbol(tokens[i]); if (result != UIntPtr.Zero) { tokens[i] = AStringUtils.IntToHex(result, 8); continue; } } //not a register or symbol //One last attempt to fix it, check if it is the last symbol, if not add it. (perhaps the symbol got split into tokens) if (i < tokens.Length - 1) { tokens[i + 1] = tokens[i] + tokens[i + 1]; //(if not, it will error out eventually anyhow) tokens[i] = ""; //empty } else { hasError = true; return(result); } } else { //it's not a real token switch (tokens[i][0]) { case '*': hasMultiplication = true; break; case '[': case ']': hasPointer = true; break; } } } } mathstring = ""; for (i = 0; i < tokens.Length; i++) { mathstring += tokens[i]; } if (hasPointer) { result = GetAddressFromPointer(mathstring, out error); if (!error) { result += offset; return(result); } //it has a pointer notation but the pointer didn't get handled... ERROR! hasError = true; return(result); } //handle the math string if (hasMultiplication) { //first do the multiplications for (i = 0; i < tokens.Length; i++) { if (tokens[i] == "*") { //multiply the left and right tokens[i - 1] = AStringUtils.IntToHex(AStringUtils.StrToQWordEx("0x" + tokens[i - 1]) * AStringUtils.StrToQWord("0x" + tokens[i + 1]), 8); tokens[i] = ""; tokens[i + 1] = ""; } } } result = UIntPtr.Zero; //handle addition and subtraction nextoperation = calcAddition; for (i = 0; i < tokens.Length; i++) { if (tokens[i].Length > 0) { switch (tokens[i][0]) { case '+': nextoperation = calcAddition; break; case '-': { if (nextoperation == calcSubstraction) { nextoperation = calcAddition; } else //--=+ { nextoperation = calcSubstraction; } } break; default: //else of case; { //do the calculation switch (nextoperation) { case calcAddition: result = (UIntPtr)(result.ToUInt64() + AStringUtils.StrToQWordEx("0x" + tokens[i])); break; case calcSubstraction: result = (UIntPtr)(result.ToUInt64() + AStringUtils.StrToQWordEx("0x" + tokens[i])); break; } } break; } } //end of if length(tokens[i])... } return(result); }
public Boolean ParseAsPointer(String s, AStringArray list) { //parse the string var currentLevel = 0; var prolog = true; var temps = ""; var isPointer = false; for (var i = 0; i < s.Length; i++) { if (s[i] == '[') { if (prolog) { currentLevel += 1; isPointer = true; } else { return(false); //bracket open after the prolog is not allowed } } else { if (prolog) { if (!UArrayUtils.InArray(s[i], '\t', ' ')) //no space or tab { prolog = false; } } if (!prolog) { //definition, currentLevel is set, now parse till last ] (currentLevel=0) if (s[i] == ']') //end of a level { currentLevel -= 1; if (temps == "") { temps = "+0"; } list.Add(temps); temps = ""; if (currentLevel < 0) { return(false); } continue; } temps += s[i]; } } } if (temps == "") { temps = "+0"; } if ((isPointer) && (temps != "")) { list.Add(temps); } if (currentLevel > 0) { return(false); } return(isPointer); }