1
0
Fork 0
x64dbg/x64_dbg_dbg/memory.cpp

198 lines
5.8 KiB
C++

#include "memory.h"
#include "debugger.h"
uint memfindbaseaddr(HANDLE hProcess, uint addr, uint* size)
{
MEMORY_BASIC_INFORMATION mbi;
DWORD numBytes;
uint MyAddress=0, newAddress=0;
do
{
numBytes=VirtualQueryEx(hProcess, (LPCVOID)MyAddress, &mbi, sizeof(mbi));
newAddress=(uint)mbi.BaseAddress+mbi.RegionSize;
if(mbi.State==MEM_COMMIT and addr<newAddress and addr>=MyAddress)
{
if(size)
*size=mbi.RegionSize;
return (uint)mbi.BaseAddress;
}
if(newAddress<=MyAddress)
numBytes=0;
else
MyAddress=newAddress;
}
while(numBytes);
return 0;
}
bool memread(HANDLE hProcess, const void* lpBaseAddress, void* lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesRead)
{
if(!hProcess or !lpBaseAddress or !lpBuffer or !nSize) //generic failures
return false;
SIZE_T read=0;
DWORD oldprotect=0;
bool ret=MemoryReadSafe(hProcess, (void*)lpBaseAddress, lpBuffer, nSize, &read); //try 'normal' RPM
if(ret and read==nSize) //'normal' RPM worked!
{
if(lpNumberOfBytesRead)
*lpNumberOfBytesRead=read;
return true;
}
for(uint i=0; i<nSize; i++) //read byte-per-byte
{
unsigned char* curaddr=(unsigned char*)lpBaseAddress+i;
unsigned char* curbuf=(unsigned char*)lpBuffer+i;
ret=MemoryReadSafe(hProcess, curaddr, curbuf, 1, 0); //try 'normal' RPM
if(!ret) //we failed
{
if(lpNumberOfBytesRead)
*lpNumberOfBytesRead=i;
SetLastError(ERROR_PARTIAL_COPY);
return false;
}
}
return true;
}
bool memwrite(HANDLE hProcess, void* lpBaseAddress, const void* lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesWritten)
{
if(!hProcess or !lpBaseAddress or !lpBuffer or !nSize) //generic failures
return false;
SIZE_T written=0;
DWORD oldprotect=0;
bool ret=MemoryWriteSafe(hProcess, lpBaseAddress, lpBuffer, nSize, &written);
if(ret and written==nSize) //'normal' WPM worked!
{
if(lpNumberOfBytesWritten)
*lpNumberOfBytesWritten=written;
return true;
}
for(uint i=0; i<nSize; i++) //write byte-per-byte
{
unsigned char* curaddr=(unsigned char*)lpBaseAddress+i;
unsigned char* curbuf=(unsigned char*)lpBuffer+i;
ret=MemoryWriteSafe(hProcess, curaddr, curbuf, 1, 0); //try 'normal' WPM
if(!ret) //we failed
{
if(lpNumberOfBytesWritten)
*lpNumberOfBytesWritten=i;
SetLastError(ERROR_PARTIAL_COPY);
return false;
}
}
return true;
}
bool memisvalidreadptr(HANDLE hProcess, uint addr)
{
unsigned char a=0;
return memread(hProcess, (void*)addr, &a, 1, 0);
}
void* memalloc(HANDLE hProcess, uint addr, DWORD size, DWORD fdProtect)
{
return VirtualAllocEx(hProcess, (void*)addr, size, MEM_RESERVE|MEM_COMMIT, fdProtect);
}
void memfree(HANDLE hProcess, uint addr)
{
VirtualFreeEx(hProcess, (void*)addr, 0, MEM_RELEASE);
}
static int formathexpattern(char* string)
{
int len=strlen(string);
_strupr(string);
char* new_string=(char*)emalloc(len+1, "formathexpattern:new_string");
memset(new_string, 0, len+1);
for(int i=0,j=0; i<len; i++)
if(string[i]=='?' or isxdigit(string[i]))
j+=sprintf(new_string+j, "%c", string[i]);
strcpy(string, new_string);
efree(new_string, "formathexpattern:new_string");
return strlen(string);
}
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);
len=formathexpattern(newtext);
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(newtext[i]=='?') //wildcard
{
newByte.n[j].all=true; //match anything
newByte.n[j].n=0;
j++;
}
else //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++;
}
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;
}