1
0
Fork 0
x64dbg/x64_dbg_dbg/_exports.cpp

913 lines
28 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"
static bool bOnlyCipAutoComments = false;
extern "C" DLL_EXPORT duint _dbg_memfindbaseaddr(duint addr, duint* size)
{
return memfindbaseaddr(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)
{
CriticalSectionLocker locker(LockMemoryPages);
int pagecount = (int)memoryPages.size();
memset(memmap, 0, sizeof(MEMMAP));
memmap->count = pagecount;
if(!pagecount)
return true;
memmap->page = (MEMPAGE*)BridgeAlloc(sizeof(MEMPAGE) * pagecount);
memset(memmap->page, 0, sizeof(MEMPAGE)*pagecount);
int j = 0;
for(MemoryMap::iterator i = memoryPages.begin(); i != memoryPages.end(); ++i, j++)
memcpy(&memmap->page[j], &i->second, 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 != GetContextDataEx(hActiveThread, UE_EFLAGS))
{
cacheFlags = GetContextDataEx(hActiveThread, 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_s(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 = (int)strlen(filename);
while(filename[len] != '\\' and len != 0)
len--;
if(len)
len++;
sprintf(addrinfo->comment, "%s:%u", filename + len, line.LineNumber);
retval = true;
}
else if(!bOnlyCipAutoComments || addr == GetContextDataEx(hActiveThread, UE_CIP)) //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 = GetContextDataEx(hActiveThread, UE_RAX);
#else
r.cax = (duint)GetContextDataEx(hActiveThread, UE_EAX);
#endif // _WIN64
#ifdef _WIN64
r.ccx = GetContextDataEx(hActiveThread, UE_RCX);
#else
r.ccx = (duint)GetContextDataEx(hActiveThread, UE_ECX);
#endif // _WIN64
#ifdef _WIN64
r.cdx = GetContextDataEx(hActiveThread, UE_RDX);
#else
r.cdx = (duint)GetContextDataEx(hActiveThread, UE_EDX);
#endif // _WIN64
#ifdef _WIN64
r.cbx = GetContextDataEx(hActiveThread, UE_RBX);
#else
r.cbx = (duint)GetContextDataEx(hActiveThread, UE_EBX);
#endif // _WIN64
#ifdef _WIN64
r.cbp = GetContextDataEx(hActiveThread, UE_RBP);
#else
r.cbp = (duint)GetContextDataEx(hActiveThread, UE_EBP);
#endif // _WIN64
#ifdef _WIN64
r.csi = GetContextDataEx(hActiveThread, UE_RSI);
#else
r.csi = (duint)GetContextDataEx(hActiveThread, UE_ESI);
#endif // _WIN64
#ifdef _WIN64
r.cdi = GetContextDataEx(hActiveThread, UE_RDI);
#else
r.cdi = (duint)GetContextDataEx(hActiveThread, UE_EDI);
#endif // _WIN64
#ifdef _WIN64
r.r8 = GetContextDataEx(hActiveThread, UE_R8);
#endif // _WIN64
#ifdef _WIN64
r.r9 = GetContextDataEx(hActiveThread, UE_R9);
#endif // _WIN64
#ifdef _WIN64
r.r10 = GetContextDataEx(hActiveThread, UE_R10);
#endif // _WIN64
#ifdef _WIN64
r.r11 = GetContextDataEx(hActiveThread, UE_R11);
#endif // _WIN64
#ifdef _WIN64
r.r12 = GetContextDataEx(hActiveThread, UE_R12);
#endif // _WIN64
#ifdef _WIN64
r.r13 = GetContextDataEx(hActiveThread, UE_R13);
#endif // _WIN64
#ifdef _WIN64
r.r14 = GetContextDataEx(hActiveThread, UE_R14);
#endif // _WIN64
#ifdef _WIN64
r.r15 = GetContextDataEx(hActiveThread, UE_R15);
#endif // _WIN64
r.csp = (duint)GetContextDataEx(hActiveThread, UE_CSP);
r.cip = (duint)GetContextDataEx(hActiveThread, UE_CIP);
r.eflags = (unsigned int)GetContextDataEx(hActiveThread, UE_EFLAGS);
r.gs = (unsigned short)(GetContextDataEx(hActiveThread, UE_SEG_GS) & 0xFFFF);
r.fs = (unsigned short)(GetContextDataEx(hActiveThread, UE_SEG_FS) & 0xFFFF);
r.es = (unsigned short)(GetContextDataEx(hActiveThread, UE_SEG_ES) & 0xFFFF);
r.ds = (unsigned short)(GetContextDataEx(hActiveThread, UE_SEG_DS) & 0xFFFF);
r.cs = (unsigned short)(GetContextDataEx(hActiveThread, UE_SEG_CS) & 0xFFFF);
r.ss = (unsigned short)(GetContextDataEx(hActiveThread, UE_SEG_SS) & 0xFFFF);
r.dr0 = (duint)GetContextDataEx(hActiveThread, UE_DR0);
r.dr1 = (duint)GetContextDataEx(hActiveThread, UE_DR1);
r.dr2 = (duint)GetContextDataEx(hActiveThread, UE_DR2);
r.dr3 = (duint)GetContextDataEx(hActiveThread, UE_DR3);
r.dr6 = (duint)GetContextDataEx(hActiveThread, UE_DR6);
r.dr7 = (duint)GetContextDataEx(hActiveThread, 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, ",");
}
}
if(BridgeSettingGetUint("Disassembler", "OnlyCipAutoComments", &setting))
{
if(setting)
bOnlyCipAutoComments = true;
else
bOnlyCipAutoComments = false;
}
}
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;
int len = Disasm(&disasm);
if(len == UNKNOWN_OPCODE)
len = 1;
uint i = 0;
BASIC_INSTRUCTION_INFO* basicinfo = (BASIC_INSTRUCTION_INFO*)param2;
fillbasicinfo(&disasm, basicinfo);
basicinfo->size = len;
}
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;
case DBG_WIN_EVENT:
{
return (uint)pluginwinevent((MSG*)param1, (long*)param2);
}
break;
case DBG_WIN_EVENT_GLOBAL:
{
return (uint)pluginwineventglobal((MSG*)param1);
}
break;
}
return 0;
}