parent
a8488322da
commit
f476569458
|
@ -918,3 +918,46 @@ CMDRESULT cbInstrGetstr(int argc, char* argv[])
|
|||
efree(string, "cbInstrGetstr:string");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrFind(int argc, char* argv[])
|
||||
{
|
||||
if(argc<3)
|
||||
{
|
||||
dputs("not enough arguments!");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
uint addr=0;
|
||||
if(!valfromstring(argv[1], &addr, false))
|
||||
return STATUS_ERROR;
|
||||
char pattern[deflen]="";
|
||||
//remove # from the start and end of the pattern (ODBGScript support)
|
||||
if(argv[2][0]=='#')
|
||||
strcpy(pattern, argv[2]+1);
|
||||
else
|
||||
strcpy(pattern, argv[2]);
|
||||
int len=strlen(pattern);
|
||||
if(pattern[len-1]=='#')
|
||||
pattern[len-1]='\0';
|
||||
uint size=0;
|
||||
uint base=memfindbaseaddr(fdProcessInfo->hProcess, addr, &size);
|
||||
if(!base)
|
||||
{
|
||||
dprintf("invalid memory address "fhex"!\n", addr);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
unsigned char* data=(unsigned char*)emalloc(size, "cbInstrFind:data");
|
||||
if(!memread(fdProcessInfo->hProcess, (const void*)base, data, size, 0))
|
||||
{
|
||||
efree(data, "cbInstrFind:data");
|
||||
dputs("failed to read memory!");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
uint start=addr-base;
|
||||
uint foundoffset=memfindpattern(data+start, size-start, pattern);
|
||||
uint result=0;
|
||||
if(foundoffset!=-1)
|
||||
result=addr+foundoffset;
|
||||
varset("$result", result, false);
|
||||
DbgCmdExec("$result");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
|
|
@ -50,4 +50,6 @@ CMDRESULT cbInstrRefStr(int argc, char* argv[]);
|
|||
CMDRESULT cbInstrSetstr(int argc, char* argv[]);
|
||||
CMDRESULT cbInstrGetstr(int argc, char* argv[]);
|
||||
|
||||
CMDRESULT cbInstrFind(int argc, char* argv[]);
|
||||
|
||||
#endif // _INSTRUCTIONS_H
|
||||
|
|
|
@ -98,3 +98,86 @@ void memfree(HANDLE hProcess, uint addr)
|
|||
{
|
||||
VirtualFreeEx(hProcess, (void*)addr, 0, MEM_RELEASE);
|
||||
}
|
||||
|
||||
static bool patterntransform(const char* text, std::vector<PATTERNBYTE>* pattern)
|
||||
{
|
||||
if(!text or !pattern)
|
||||
return false;
|
||||
pattern->clear();
|
||||
int len=strlen(text);
|
||||
if(!len)
|
||||
return false;
|
||||
char* newtext=(char*)emalloc(len+2, "transformpattern:newtext");
|
||||
strcpy(newtext, text);
|
||||
if(len%2) //not a multiple of 2
|
||||
{
|
||||
newtext[len]='?';
|
||||
newtext[len+1]='\0';
|
||||
len++;
|
||||
}
|
||||
PATTERNBYTE newByte;
|
||||
for(int i=0,j=0; i<len; i++)
|
||||
{
|
||||
if(isxdigit(newtext[i])) //hex
|
||||
{
|
||||
char x[2]="";
|
||||
*x=newtext[i];
|
||||
unsigned int val=0;
|
||||
sscanf(x, "%x", &val);
|
||||
newByte.n[j].all=false;
|
||||
newByte.n[j].n=val&0xF;
|
||||
j++;
|
||||
}
|
||||
else if(newtext[i]=='?') //wildcard
|
||||
{
|
||||
newByte.n[j].all=true; //match anything
|
||||
newByte.n[j].n=0;
|
||||
j++;
|
||||
}
|
||||
else //dafug dude..
|
||||
return false; //invalid pattern format
|
||||
if(j==2) //two nibbles = one byte
|
||||
{
|
||||
j=0;
|
||||
pattern->push_back(newByte);
|
||||
}
|
||||
}
|
||||
efree(newtext, "transformpattern:newtext");
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool patternmatchbyte(unsigned char byte, PATTERNBYTE* pbyte)
|
||||
{
|
||||
unsigned char n1=(byte>>4)&0xF;
|
||||
unsigned char n2=byte&0xF;
|
||||
int matched=0;
|
||||
if(pbyte->n[0].all)
|
||||
matched++;
|
||||
else if(pbyte->n[0].n==n1)
|
||||
matched++;
|
||||
if(pbyte->n[1].all)
|
||||
matched++;
|
||||
else if(pbyte->n[1].n==n2)
|
||||
matched++;
|
||||
return (matched==2);
|
||||
}
|
||||
|
||||
uint memfindpattern(unsigned char* data, uint size, const char* pattern)
|
||||
{
|
||||
std::vector<PATTERNBYTE> searchpattern;
|
||||
if(!patterntransform(pattern, &searchpattern))
|
||||
return -1;
|
||||
int searchpatternsize=searchpattern.size();
|
||||
for(uint i=0,pos=0; i<size; i++) //search for the pattern
|
||||
{
|
||||
if(patternmatchbyte(data[i], &searchpattern.at(pos))) //check if our pattern matches the current byte
|
||||
{
|
||||
pos++;
|
||||
if(pos==searchpatternsize) //everything matched
|
||||
return i-searchpatternsize+1;
|
||||
}
|
||||
else
|
||||
pos=0; //reset current pattern position
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,18 @@
|
|||
|
||||
#include "_global.h"
|
||||
|
||||
#define PAGE_SIZE 0x1000
|
||||
#define PAGE_SIZE 0x1000 //TODO: better stuff here
|
||||
|
||||
struct PATTERNNIBBLE
|
||||
{
|
||||
unsigned char n;
|
||||
bool all;
|
||||
};
|
||||
|
||||
struct PATTERNBYTE
|
||||
{
|
||||
PATTERNNIBBLE n[2];
|
||||
};
|
||||
|
||||
uint memfindbaseaddr(HANDLE hProcess, uint addr, uint* size);
|
||||
bool memread(HANDLE hProcess, const void* lpBaseAddress, void* lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesRead);
|
||||
|
@ -11,5 +22,6 @@ bool memwrite(HANDLE hProcess, void* lpBaseAddress, const void* lpBuffer, SIZE_T
|
|||
bool memisvalidreadptr(HANDLE hProcess, uint addr);
|
||||
void* memalloc(HANDLE hProcess, uint addr, DWORD size, DWORD fdProtect);
|
||||
void memfree(HANDLE hProcess, uint addr);
|
||||
uint memfindpattern(unsigned char* data, uint size, const char* pattern);
|
||||
|
||||
#endif // _MEMORY_H
|
||||
|
|
|
@ -152,6 +152,8 @@ static void registercommands()
|
|||
|
||||
cmdnew(cmd, "setstr\1strset", cbInstrSetstr, false); //set a string variable
|
||||
cmdnew(cmd, "getstr\1strget", cbInstrGetstr, false); //get a string variable
|
||||
|
||||
cmdnew(cmd, "find", cbInstrFind, true); //find a pattern
|
||||
}
|
||||
|
||||
static bool cbCommandProvider(char* cmd, int maxlen)
|
||||
|
|
Loading…
Reference in New Issue