1
0
Fork 0
x64dbg/x64_dbg_dbg/_exports.cpp

1027 lines
32 KiB
C++

#include "_exports.h"
#include "memory.h"
#include "debugger.h"
#include "value.h"
#include "addrinfo.h"
#include "console.h"
#include "threading.h"
#include "breakpoint.h"
#include "disasm_helper.h"
#include "simplescript.h"
#include "symbolinfo.h"
#include "assemble.h"
#include "stackinfo.h"
#include "thread.h"
#include "disasm_fast.h"
#include "plugin_loader.h"
#include "_dbgfunctions.h"
extern "C" DLL_EXPORT duint _dbg_memfindbaseaddr(duint addr, duint* size)
{
return memfindbaseaddr(fdProcessInfo->hProcess, addr, size);
}
extern "C" DLL_EXPORT bool _dbg_memread(duint addr, unsigned char* dest, duint size, duint* read)
{
return memread(fdProcessInfo->hProcess, (void*)addr, dest, size, read);
}
extern "C" DLL_EXPORT bool _dbg_memwrite(duint addr, const unsigned char* src, duint size, duint* written)
{
return memwrite(fdProcessInfo->hProcess, (void*)addr, src, size, written);
}
extern "C" DLL_EXPORT bool _dbg_memmap(MEMMAP* memmap)
{
memset(memmap, 0, sizeof(MEMMAP));
MEMORY_BASIC_INFORMATION mbi;
SIZE_T numBytes;
uint MyAddress=0, newAddress=0;
uint curAllocationBase=0;
bool bListAllPages = false; //TODO: settings for this
std::vector<MEMPAGE> pageVector;
do
{
numBytes=VirtualQueryEx(fdProcessInfo->hProcess, (LPCVOID)MyAddress, &mbi, sizeof(mbi));
if(mbi.State==MEM_COMMIT)
{
if(bListAllPages || curAllocationBase!=(uint)mbi.AllocationBase) //only list allocation bases
{
curAllocationBase=(uint)mbi.AllocationBase;
MEMPAGE curPage;
*curPage.info=0;
modnamefromaddr(MyAddress, curPage.info, true);
memcpy(&curPage.mbi, &mbi, sizeof(mbi));
pageVector.push_back(curPage);
}
else
pageVector.at(pageVector.size()-1).mbi.RegionSize+=mbi.RegionSize;
}
newAddress=(uint)mbi.BaseAddress+mbi.RegionSize;
if(newAddress<=MyAddress)
numBytes=0;
else
MyAddress=newAddress;
}
while(numBytes);
int pagecount;
//filter executable sections
if(bListAllPages)
{
pagecount=pageVector.size();
char curMod[MAX_MODULE_SIZE]="";
for(int i=pagecount-1,curIdx=0; i>-1; i--)
{
if(pageVector.at(i).info[0]) //there is a module
{
if(!scmp(curMod, pageVector.at(i).info)) //mod is not the current mod
{
strcpy(curMod, pageVector.at(i).info);
curIdx=i;
}
else //current mod
{
pageVector.at(curIdx).mbi.RegionSize+=pageVector.at(i).mbi.RegionSize;
pageVector.erase(pageVector.begin()+i);
curIdx--; //the index changes when you remove an entry
}
}
}
}
//process file sections
pagecount=pageVector.size();
char curMod[MAX_MODULE_SIZE]="";
for(int i=pagecount-1; i>-1; i--)
{
if(pageVector.at(i).info[0]) //there is a module
{
if(!scmp(curMod, pageVector.at(i).info)) //mod is not the current mod
{
strcpy(curMod, pageVector.at(i).info);
HMODULE hMod=(HMODULE)modbasefromname(curMod);
if(!hMod)
continue;
char curModPath[MAX_PATH]="";
if(!GetModuleFileNameExA(fdProcessInfo->hProcess, hMod, curModPath, MAX_PATH))
continue;
int SectionNumber=GetPE32Data(curModPath, 0, UE_SECTIONNUMBER);
MEMPAGE newPage;
pageVector.erase(pageVector.begin()+i); //remove the SizeOfImage page
for(int j=SectionNumber-1; j>-1; j--)
{
memset(&newPage, 0, sizeof(MEMPAGE));
VirtualQueryEx(fdProcessInfo->hProcess, (LPCVOID)((uint)hMod+GetPE32Data(curModPath, j, UE_SECTIONVIRTUALOFFSET)), &newPage.mbi, sizeof(MEMORY_BASIC_INFORMATION));
uint SectionSize=GetPE32Data(curModPath, j, UE_SECTIONVIRTUALSIZE);
if(SectionSize%PAGE_SIZE) //unaligned page size
SectionSize+=PAGE_SIZE-(SectionSize%PAGE_SIZE); //fix this
if(SectionSize)
newPage.mbi.RegionSize=SectionSize;
const char* SectionName=(const char*)GetPE32Data(curModPath, j, UE_SECTIONNAME);
if(!SectionName)
SectionName="";
int len=strlen(SectionName);
int escape_count=0;
for(int k=0; k<len; k++)
if(SectionName[k]=='\\' or SectionName[k]=='\"' or !isprint(SectionName[k]))
escape_count++;
char* SectionNameEscaped=(char*)emalloc(len+escape_count*3+1, "_dbg_memmap:SectionNameEscaped");
memset(SectionNameEscaped, 0, len+escape_count*3+1);
for(int k=0,l=0; k<len; k++)
{
switch(SectionName[k])
{
case '\t':
l+=sprintf(SectionNameEscaped+l, "\\t");
break;
case '\f':
l+=sprintf(SectionNameEscaped+l, "\\f");
break;
case '\v':
l+=sprintf(SectionNameEscaped+l, "\\v");
break;
case '\n':
l+=sprintf(SectionNameEscaped+l, "\\n");
break;
case '\r':
l+=sprintf(SectionNameEscaped+l, "\\r");
break;
case '\\':
l+=sprintf(SectionNameEscaped+l, "\\\\");
break;
case '\"':
l+=sprintf(SectionNameEscaped+l, "\\\"");
break;
default:
if(!isprint(SectionName[k])) //unknown unprintable character
l+=sprintf(SectionNameEscaped+l, "\\x%.2X", SectionName[k]);
else
l+=sprintf(SectionNameEscaped+l, "%c", SectionName[k]);
break;
}
}
sprintf(newPage.info, " \"%s\"", SectionNameEscaped);
efree(SectionNameEscaped, "_dbg_memmap:SectionNameEscaped");
pageVector.insert(pageVector.begin()+i, newPage);
}
memset(&newPage, 0, sizeof(MEMPAGE));
VirtualQueryEx(fdProcessInfo->hProcess, (LPCVOID)hMod, &newPage.mbi, sizeof(MEMORY_BASIC_INFORMATION));
strcpy(newPage.info, curMod);
pageVector.insert(pageVector.begin()+i, newPage);
}
}
}
//process vector
memmap->count=pagecount=pageVector.size();
memmap->page=(MEMPAGE*)BridgeAlloc(sizeof(MEMPAGE)*pagecount);
memset(memmap->page, 0, sizeof(MEMPAGE)*pagecount);
for(int i=0; i<pagecount; i++)
memcpy(&memmap->page[i], &pageVector.at(i), sizeof(MEMPAGE));
return true;
}
extern "C" DLL_EXPORT bool _dbg_memisvalidreadptr(duint addr)
{
return memisvalidreadptr(fdProcessInfo->hProcess, addr);
}
extern "C" DLL_EXPORT bool _dbg_valfromstring(const char* string, duint* value)
{
return valfromstring(string, value);
}
extern "C" DLL_EXPORT bool _dbg_isdebugging()
{
if(IsFileBeingDebugged())
return true;
return false;
}
extern "C" DLL_EXPORT bool _dbg_isjumpgoingtoexecute(duint addr)
{
static uint cacheFlags;
static uint cacheAddr;
static bool cacheResult;
if(cacheAddr!=addr or cacheFlags!=GetContextData(UE_EFLAGS))
{
cacheFlags=GetContextData(UE_EFLAGS);
cacheAddr=addr;
cacheResult=IsJumpGoingToExecuteEx(fdProcessInfo->hProcess, fdProcessInfo->hThread, (ULONG_PTR)cacheAddr, cacheFlags);
}
return cacheResult;
}
extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDRINFO* addrinfo)
{
if(!DbgIsDebugging())
return false;
bool retval=false;
if(addrinfo->flags&flagmodule) //get module
{
char module[64]="";
if(modnamefromaddr(addr, module, false) and strlen(module)<MAX_MODULE_SIZE) //get module name
{
strcpy(addrinfo->module, module);
retval=true;
}
}
if(addrinfo->flags&flaglabel)
{
if(labelget(addr, addrinfo->label))
retval=true;
else //no user labels
{
DWORD64 displacement=0;
char buffer[sizeof(SYMBOL_INFO) + MAX_LABEL_SIZE * sizeof(char)];
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
pSymbol->MaxNameLen = MAX_LABEL_SIZE;
if(SymFromAddr(fdProcessInfo->hProcess, (DWORD64)addr, &displacement, pSymbol) and !displacement)
{
if(settingboolget("Engine", "UndecorateSymbolNames") or !UnDecorateSymbolName(pSymbol->Name, addrinfo->label, MAX_LABEL_SIZE, UNDNAME_COMPLETE))
strcpy(addrinfo->label, pSymbol->Name);
retval=true;
}
if(!retval) //search for CALL <jmp.&user32.MessageBoxA>
{
BASIC_INSTRUCTION_INFO basicinfo;
memset(&basicinfo, 0, sizeof(BASIC_INSTRUCTION_INFO));
if(disasmfast(addr, &basicinfo) && basicinfo.branch && !basicinfo.call && basicinfo.memory.value) //thing is a JMP
{
uint val=0;
if(memread(fdProcessInfo->hProcess, (const void*)basicinfo.memory.value, &val, sizeof(val), 0))
{
if(SymFromAddr(fdProcessInfo->hProcess, (DWORD64)val, &displacement, pSymbol) and !displacement)
{
if(settingboolget("Engine", "UndecorateSymbolNames") or !UnDecorateSymbolName(pSymbol->Name, addrinfo->label, MAX_LABEL_SIZE, UNDNAME_COMPLETE))
sprintf_s(addrinfo->label, "JMP.&%s", pSymbol->Name);
retval=true;
}
}
}
}
}
}
if(addrinfo->flags&flagbookmark)
{
addrinfo->isbookmark=bookmarkget(addr);
retval=true;
}
if(addrinfo->flags&flagfunction)
{
if(functionget(addr, &addrinfo->function.start, &addrinfo->function.end))
retval=true;
}
if(addrinfo->flags&flagloop)
{
if(loopget(addrinfo->loop.depth, addr, &addrinfo->loop.start, &addrinfo->loop.end))
retval=true;
}
if(addrinfo->flags&flagcomment)
{
*addrinfo->comment=0;
if(commentget(addr, addrinfo->comment))
retval=true;
else
{
DWORD dwDisplacement;
IMAGEHLP_LINE64 line;
line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
if(SymGetLineFromAddr64(fdProcessInfo->hProcess, (DWORD64)addr, &dwDisplacement, &line) and !dwDisplacement)
{
char filename[deflen]="";
strcpy(filename, line.FileName);
int len=strlen(filename);
while(filename[len]!='\\' and len!=0)
len--;
if(len)
len++;
sprintf(addrinfo->comment, "%s:%u", filename+len, line.LineNumber);
retval=true;
}
else //no line number
{
DISASM_INSTR instr;
std::string temp_string;
ADDRINFO newinfo;
char ascii[256*2]="";
char unicode[256*2]="";
memset(&instr, 0, sizeof(DISASM_INSTR));
disasmget(addr, &instr);
int len_left=MAX_COMMENT_SIZE;
for(int i=0,j=0; i<instr.argcount; i++)
{
memset(&newinfo, 0, sizeof(ADDRINFO));
newinfo.flags=flaglabel;
STRING_TYPE strtype=str_none;
if(instr.arg[i].constant==instr.arg[i].value) //avoid: call <module.label> ; addr:label
{
if(instr.type==instr_branch or !disasmgetstringat(instr.arg[i].constant, &strtype, ascii, unicode, len_left) or strtype==str_none)
continue;
switch(strtype)
{
case str_none:
break;
case str_ascii:
temp_string=instr.arg[i].mnemonic;
temp_string.append(":\"");
temp_string.append(ascii);
temp_string.append("\"");
break;
case str_unicode:
temp_string=instr.arg[i].mnemonic;
temp_string.append(":L\"");
temp_string.append(unicode);
temp_string.append("\"");
break;
}
}
else if(instr.arg[i].memvalue and (disasmgetstringat(instr.arg[i].memvalue, &strtype, ascii, unicode, len_left) or _dbg_addrinfoget(instr.arg[i].memvalue, instr.arg[i].segment, &newinfo)))
{
switch(strtype)
{
case str_none:
if(*newinfo.label)
{
temp_string="[";
temp_string.append(instr.arg[i].mnemonic);
temp_string.append("]:");
temp_string.append(newinfo.label);
}
break;
case str_ascii:
temp_string="[";
temp_string.append(instr.arg[i].mnemonic);
temp_string.append("]:");
temp_string.append(ascii);
break;
case str_unicode:
temp_string="[";
temp_string.append(instr.arg[i].mnemonic);
temp_string.append("]:");
temp_string.append(unicode);
break;
}
}
else if(instr.arg[i].value and (disasmgetstringat(instr.arg[i].value, &strtype, ascii, unicode, len_left) or _dbg_addrinfoget(instr.arg[i].value, instr.arg[i].segment, &newinfo)))
{
if(instr.type!=instr_normal) //stack/jumps (eg add esp,4 or jmp 401110) cannot directly point to strings
strtype=str_none;
switch(strtype)
{
case str_none:
if(*newinfo.label)
{
temp_string=instr.arg[i].mnemonic;
temp_string.append(":");
temp_string.append(newinfo.label);
}
break;
case str_ascii:
temp_string=instr.arg[i].mnemonic;
temp_string.append(":\"");
temp_string.append(ascii);
temp_string.append("\"");
break;
case str_unicode:
temp_string=instr.arg[i].mnemonic;
temp_string.append(":L\"");
temp_string.append(unicode);
temp_string.append("\"");
break;
}
}
else
continue;
if(!strstr(addrinfo->comment, temp_string.c_str()))
{
unsigned int maxlen=MAX_COMMENT_SIZE-j-1;
if(maxlen<temp_string.length())
temp_string.at(maxlen-1)=0;
if(j)
j+=sprintf(addrinfo->comment+j, ", %s", temp_string.c_str());
else
j+=sprintf(addrinfo->comment+j, "%s", temp_string.c_str());
retval=true;
}
}
}
}
}
return retval;
}
extern "C" DLL_EXPORT bool _dbg_addrinfoset(duint addr, ADDRINFO* addrinfo)
{
bool retval=false;
if(addrinfo->flags&flaglabel) //set label
{
if(labelset(addr, addrinfo->label, true))
retval=true;
}
if(addrinfo->flags&flagcomment) //set comment
{
if(commentset(addr, addrinfo->comment, true))
retval=true;
}
if(addrinfo->flags&flagbookmark) //set bookmark
{
if(addrinfo->isbookmark)
retval=bookmarkset(addr, true);
else
retval=bookmarkdel(addr);
}
return retval;
}
extern "C" DLL_EXPORT int _dbg_bpgettypeat(duint addr)
{
static uint cacheAddr;
static int cacheBpCount;
static int cacheResult;
int bpcount=bpgetlist(0);
if(cacheAddr!=addr or cacheBpCount!=bpcount)
{
BREAKPOINT bp;
cacheAddr=addr;
cacheResult=0;
cacheBpCount=bpcount;
if(bpget(addr, BPNORMAL, 0, &bp))
if(bp.enabled)
cacheResult|=bp_normal;
if(bpget(addr, BPHARDWARE, 0, &bp))
if(bp.enabled)
cacheResult|=bp_hardware;
if(bpget(addr, BPMEMORY, 0, &bp))
if(bp.enabled)
cacheResult|=bp_memory;
}
return cacheResult;
}
extern "C" DLL_EXPORT bool _dbg_getregdump(REGDUMP* regdump)
{
if(!DbgIsDebugging())
{
memset(regdump, 0, sizeof(REGDUMP));
return true;
}
REGDUMP r;
#ifdef _WIN64
r.cax=GetContextData(UE_RAX);
#else
r.cax=(duint)GetContextData(UE_EAX);
#endif // _WIN64
#ifdef _WIN64
r.ccx=GetContextData(UE_RCX);
#else
r.ccx=(duint)GetContextData(UE_ECX);
#endif // _WIN64
#ifdef _WIN64
r.cdx=GetContextData(UE_RDX);
#else
r.cdx=(duint)GetContextData(UE_EDX);
#endif // _WIN64
#ifdef _WIN64
r.cbx=GetContextData(UE_RBX);
#else
r.cbx=(duint)GetContextData(UE_EBX);
#endif // _WIN64
#ifdef _WIN64
r.cbp=GetContextData(UE_RBP);
#else
r.cbp=(duint)GetContextData(UE_EBP);
#endif // _WIN64
#ifdef _WIN64
r.csi=GetContextData(UE_RSI);
#else
r.csi=(duint)GetContextData(UE_ESI);
#endif // _WIN64
#ifdef _WIN64
r.cdi=GetContextData(UE_RDI);
#else
r.cdi=(duint)GetContextData(UE_EDI);
#endif // _WIN64
#ifdef _WIN64
r.r8=GetContextData(UE_R8);
#endif // _WIN64
#ifdef _WIN64
r.r9=GetContextData(UE_R9);
#endif // _WIN64
#ifdef _WIN64
r.r10=GetContextData(UE_R10);
#endif // _WIN64
#ifdef _WIN64
r.r11=GetContextData(UE_R11);
#endif // _WIN64
#ifdef _WIN64
r.r12=GetContextData(UE_R12);
#endif // _WIN64
#ifdef _WIN64
r.r13=GetContextData(UE_R13);
#endif // _WIN64
#ifdef _WIN64
r.r14=GetContextData(UE_R14);
#endif // _WIN64
#ifdef _WIN64
r.r15=GetContextData(UE_R15);
#endif // _WIN64
r.csp=(duint)GetContextData(UE_CSP);
r.cip=(duint)GetContextData(UE_CIP);
r.eflags=(duint)GetContextData(UE_EFLAGS);
r.gs=(unsigned short)(GetContextData(UE_SEG_GS)&0xFFFF);
r.fs=(unsigned short)(GetContextData(UE_SEG_FS)&0xFFFF);
r.es=(unsigned short)(GetContextData(UE_SEG_ES)&0xFFFF);
r.ds=(unsigned short)(GetContextData(UE_SEG_DS)&0xFFFF);
r.cs=(unsigned short)(GetContextData(UE_SEG_CS)&0xFFFF);
r.ss=(unsigned short)(GetContextData(UE_SEG_SS)&0xFFFF);
r.dr0=(duint)GetContextData(UE_DR0);
r.dr1=(duint)GetContextData(UE_DR1);
r.dr2=(duint)GetContextData(UE_DR2);
r.dr3=(duint)GetContextData(UE_DR3);
r.dr6=(duint)GetContextData(UE_DR6);
r.dr7=(duint)GetContextData(UE_DR7);
duint cflags=r.eflags;
r.flags.c=valflagfromstring(cflags, "cf");
r.flags.p=valflagfromstring(cflags, "pf");
r.flags.a=valflagfromstring(cflags, "af");
r.flags.z=valflagfromstring(cflags, "zf");
r.flags.s=valflagfromstring(cflags, "sf");
r.flags.t=valflagfromstring(cflags, "tf");
r.flags.i=valflagfromstring(cflags, "if");
r.flags.d=valflagfromstring(cflags, "df");
r.flags.o=valflagfromstring(cflags, "of");
memcpy(regdump, &r, sizeof(REGDUMP));
return true;
}
extern "C" DLL_EXPORT bool _dbg_valtostring(const char* string, duint* value)
{
return valtostring(string, value, true);
}
extern "C" DLL_EXPORT int _dbg_getbplist(BPXTYPE type, BPMAP* bpmap)
{
if(!bpmap)
return 0;
std::vector<BREAKPOINT> list;
int bpcount=bpgetlist(&list);
if(bpcount==0)
{
bpmap->count=0;
return 0;
}
int retcount=0;
std::vector<BRIDGEBP> bridgeList;
BRIDGEBP curBp;
unsigned short slot=0;
for(int i=0; i<bpcount; i++)
{
memset(&curBp, 0, sizeof(BRIDGEBP));
switch(type)
{
case bp_none: //all types
break;
case bp_normal: //normal
if(list[i].type!=BPNORMAL)
continue;
break;
case bp_hardware: //hardware
if(list[i].type!=BPHARDWARE)
continue;
break;
case bp_memory: //memory
if(list[i].type!=BPMEMORY)
continue;
break;
default:
return 0;
}
switch(list[i].type)
{
case BPNORMAL:
curBp.type=bp_normal;
break;
case BPHARDWARE:
curBp.type=bp_hardware;
break;
case BPMEMORY:
curBp.type=bp_memory;
break;
}
switch(((DWORD)list[i].titantype)>>8)
{
case UE_DR0:
slot=0;
break;
case UE_DR1:
slot=1;
break;
case UE_DR2:
slot=2;
break;
case UE_DR3:
slot=3;
break;
}
curBp.addr=list[i].addr;
curBp.enabled=list[i].enabled;
//TODO: fix this
if(memisvalidreadptr(fdProcessInfo->hProcess, curBp.addr))
curBp.active=true;
strcpy(curBp.mod, list[i].mod);
strcpy(curBp.name, list[i].name);
curBp.singleshoot=list[i].singleshoot;
curBp.slot=slot;
if(curBp.active)
{
bridgeList.push_back(curBp);
retcount++;
}
}
if(!retcount)
{
bpmap->count=retcount;
return retcount;
}
bpmap->count=retcount;
bpmap->bp=(BRIDGEBP*)BridgeAlloc(sizeof(BRIDGEBP)*retcount);
for(int i=0; i<retcount; i++)
memcpy(&bpmap->bp[i], &bridgeList.at(i), sizeof(BRIDGEBP));
return retcount;
}
extern "C" DLL_EXPORT uint _dbg_getbranchdestination(uint addr)
{
DISASM_INSTR instr;
memset(&instr, 0, sizeof(instr));
disasmget(addr, &instr);
if(instr.type!=instr_branch)
return 0;
if(strstr(instr.instruction, "ret"))
{
uint atcsp=DbgValFromString("@csp");
if(DbgMemIsValidReadPtr(atcsp))
return atcsp;
else
return 0;
}
else if(instr.arg[0].type==arg_memory)
return instr.arg[0].memvalue;
else
return instr.arg[0].value;
}
extern "C" DLL_EXPORT bool _dbg_functionoverlaps(uint start, uint end)
{
return functionoverlaps(start, end);
}
extern "C" DLL_EXPORT uint _dbg_sendmessage(DBGMSG type, void* param1, void* param2)
{
switch(type)
{
case DBG_SCRIPT_LOAD:
{
scriptload((const char*)param1);
}
break;
case DBG_SCRIPT_UNLOAD:
{
scriptunload();
}
break;
case DBG_SCRIPT_RUN:
{
scriptrun((int)(duint)param1);
}
break;
case DBG_SCRIPT_STEP:
{
scriptstep();
}
break;
case DBG_SCRIPT_BPTOGGLE:
{
return scriptbptoggle((int)(duint)param1);
}
break;
case DBG_SCRIPT_BPGET:
{
return scriptbpget((int)(duint)param1);
}
break;
case DBG_SCRIPT_CMDEXEC:
{
return scriptcmdexec((const char*)param1);
}
break;
case DBG_SCRIPT_ABORT:
{
scriptabort();
}
break;
case DBG_SCRIPT_GETLINETYPE:
{
return (duint)scriptgetlinetype((int)(duint)param1);
}
break;
case DBG_SCRIPT_SETIP:
{
scriptsetip((int)(duint)param1);
}
break;
case DBG_SCRIPT_GETBRANCHINFO:
{
return (duint)scriptgetbranchinfo((int)(duint)param1, (SCRIPTBRANCH*)param2);
}
break;
case DBG_SYMBOL_ENUM:
{
SYMBOLCBINFO* cbInfo=(SYMBOLCBINFO*)param1;
symenum(cbInfo->base, cbInfo->cbSymbolEnum, cbInfo->user);
}
break;
case DBG_ASSEMBLE_AT:
{
return assembleat((duint)param1, (const char*)param2, 0, 0, false);
}
break;
case DBG_MODBASE_FROM_NAME:
{
return modbasefromname((const char*)param1);
}
break;
case DBG_DISASM_AT:
{
disasmget((uint)param1, (DISASM_INSTR*)param2);
}
break;
case DBG_STACK_COMMENT_GET:
{
return stackcommentget((uint)param1, (STACK_COMMENT*)param2);
}
break;
case DBG_GET_THREAD_LIST:
{
threadgetlist((THREADLIST*)param1);
}
break;
case DBG_SETTINGS_UPDATED:
{
uint setting;
if(BridgeSettingGetUint("Engine", "CalculationType", &setting))
{
switch(setting)
{
case 0: //calc_signed
valuesetsignedcalc(true);
break;
case 1: //calc_unsigned
valuesetsignedcalc(false);
break;
}
}
if(BridgeSettingGetUint("Engine", "BreakpointType", &setting))
{
switch(setting)
{
case 0: //break_int3short
SetBPXOptions(UE_BREAKPOINT_INT3);
break;
case 1: //break_int3long
SetBPXOptions(UE_BREAKPOINT_LONG_INT3);
break;
case 2: //break_ud2
SetBPXOptions(UE_BREAKPOINT_UD2);
break;
}
}
if(BridgeSettingGetUint("Engine", "EnableDebugPrivilege", &setting))
{
if(setting)
SetEngineVariable(UE_ENGINE_SET_DEBUG_PRIVILEGE, true);
else
SetEngineVariable(UE_ENGINE_SET_DEBUG_PRIVILEGE, false);
}
char exceptionRange[MAX_SETTING_SIZE]="";
dbgclearignoredexceptions();
if(BridgeSettingGet("Exceptions", "IgnoreRange", exceptionRange))
{
char* entry=strtok(exceptionRange, ",");
while(entry)
{
unsigned long start;
unsigned long end;
if(sscanf(entry, "%08X-%08X", &start, &end)==2 && start<=end)
{
ExceptionRange range;
range.start=start;
range.end=end;
dbgaddignoredexception(range);
}
entry=strtok(0, ",");
}
}
}
break;
case DBG_DISASM_FAST_AT:
{
if(!param1 or !param2)
return 0;
unsigned char data[16];
if(!memread(fdProcessInfo->hProcess, param1, data, sizeof(data), 0))
return 0;
DISASM disasm;
memset(&disasm, 0, sizeof(disasm));
#ifdef _WIN64
disasm.Archi=64;
#endif // _WIN64
disasm.EIP=(UIntPtr)data;
disasm.VirtualAddr=(UInt64)param1;
uint i=0;
fillbasicinfo(&disasm, (BASIC_INSTRUCTION_INFO*)param2);
}
break;
case DBG_MENU_ENTRY_CLICKED:
{
int hEntry=(int)(uint)param1;
pluginmenucall(hEntry);
}
break;
case DBG_FUNCTION_GET:
{
FUNCTION_LOOP_INFO* info=(FUNCTION_LOOP_INFO*)param1;
return (uint)functionget(info->addr, &info->start, &info->end);
}
break;
case DBG_FUNCTION_OVERLAPS:
{
FUNCTION_LOOP_INFO* info=(FUNCTION_LOOP_INFO*)param1;
return (uint)functionoverlaps(info->start, info->end);
}
break;
case DBG_FUNCTION_ADD:
{
FUNCTION_LOOP_INFO* info=(FUNCTION_LOOP_INFO*)param1;
return (uint)functionadd(info->start, info->end, info->manual);
}
break;
case DBG_FUNCTION_DEL:
{
FUNCTION_LOOP_INFO* info=(FUNCTION_LOOP_INFO*)param1;
return (uint)functiondel(info->addr);
}
break;
case DBG_LOOP_GET:
{
FUNCTION_LOOP_INFO* info=(FUNCTION_LOOP_INFO*)param1;
return (uint)loopget(info->depth, info->addr, &info->start, &info->end);
}
break;
case DBG_LOOP_OVERLAPS:
{
FUNCTION_LOOP_INFO* info=(FUNCTION_LOOP_INFO*)param1;
return (uint)loopoverlaps(info->depth, info->start, info->end, 0);
}
break;
case DBG_LOOP_ADD:
{
FUNCTION_LOOP_INFO* info=(FUNCTION_LOOP_INFO*)param1;
return (uint)loopadd(info->start, info->end, info->manual);
}
break;
case DBG_LOOP_DEL:
{
FUNCTION_LOOP_INFO* info=(FUNCTION_LOOP_INFO*)param1;
return (uint)loopdel(info->depth, info->addr);
}
break;
case DBG_IS_RUN_LOCKED:
{
return (uint)waitislocked(WAITID_RUN);
}
break;
case DBG_IS_BP_DISABLED:
{
BREAKPOINT bp;
if(bpget((uint)param1, BPNORMAL, 0, &bp))
return !(uint)bp.enabled;
return (uint)false;
}
break;
case DBG_SET_AUTO_COMMENT_AT:
{
return (uint)commentset((uint)param1, (const char*)param2, false);
}
break;
case DBG_DELETE_AUTO_COMMENT_RANGE:
{
commentdelrange((uint)param1, (uint)param2);
}
break;
case DBG_SET_AUTO_LABEL_AT:
{
return (uint)labelset((uint)param1, (const char*)param2, false);
}
break;
case DBG_DELETE_AUTO_LABEL_RANGE:
{
labeldelrange((uint)param1, (uint)param2);
}
break;
case DBG_SET_AUTO_BOOKMARK_AT:
{
return (uint)bookmarkset((uint)param1, false);
}
break;
case DBG_DELETE_AUTO_BOOKMARK_RANGE:
{
bookmarkdelrange((uint)param1, (uint)param2);
}
break;
case DBG_SET_AUTO_FUNCTION_AT:
{
return (uint)functionadd((uint)param1, (uint)param2, false);
}
break;
case DBG_DELETE_AUTO_FUNCTION_RANGE:
{
functiondelrange((uint)param1, (uint)param2);
}
break;
case DBG_GET_STRING_AT:
{
STRING_TYPE strtype;
char string[512]="";
if(disasmgetstringat((uint)param1, &strtype, string, string, 500))
{
if(strtype==str_ascii)
sprintf((char*)param2, "\"%s\"", string);
else //unicode
sprintf((char*)param2, "L\"%s\"", string);
return true;
}
return false;
}
break;
case DBG_GET_FUNCTIONS:
{
return (uint)dbgfunctionsget();
}
break;
}
return 0;
}