Skip to content

Commit

Permalink
Fixed issue (#5), Implemented enhancement #3, Fixed a critical bug.
Browse files Browse the repository at this point in the history
  • Loading branch information
0ffffffffh committed Feb 6, 2017
1 parent 5a8035d commit 8fca492
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 55 deletions.
61 changes: 43 additions & 18 deletions x64dbgApiBreak/src/apibreak.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#include <corelib.h>
#include <pluginsdk/_scriptapi_module.h>
#include <pluginsdk/_scriptapi_symbol.h>
#include <pluginsdk/_scriptapi_debug.h>
#include <pluginsdk/bridgemain.h>
Expand Down Expand Up @@ -161,7 +160,7 @@ bool AbpNeedsReloadModuleAPIs()
{
ModuleInfo mod;

if (!GetMainModuleInfo(&mod))
if (!AbGetDebuggedModuleInfo(&mod))
return false;

return strcmp(mod.name, AbpCurrentMainModule.name) != 0;
Expand All @@ -176,7 +175,7 @@ duint AbpGetPEDataOfMainModule(duint type, int sectIndex)
{
ModuleInfo mainModule;

if (!GetMainModuleInfo(&mainModule))
if (!AbGetDebuggedModuleInfo(&mainModule))
return 0;

return AbpGetPEDataOfMainModule2(&mainModule, type, sectIndex);
Expand Down Expand Up @@ -214,14 +213,14 @@ INTERNAL_EXPORT bool AbiGetMainModuleCodeSection(ModuleSectionInfo *msi)
ModuleInfo mainModule;
DWORD flags;

if (!GetMainModuleInfo(&mainModule))
if (!AbGetDebuggedModuleInfo(&mainModule))
return 0;

for (int i = 0;i < mainModule.sectionCount;i++)
{
flags = AbpGetPEDataOfMainModule2(&mainModule, UE_SECTIONFLAGS, i);

if (flags | IMAGE_SCN_CNT_CODE)
if (flags & IMAGE_SCN_CNT_CODE)
{
msi->addr = mainModule.base + AbpGetPEDataOfMainModule2(&mainModule, UE_SECTIONVIRTUALOFFSET, i);
msi->size = AbpGetPEDataOfMainModule2(&mainModule, UE_SECTIONVIRTUALSIZE, i);
Expand All @@ -233,19 +232,51 @@ INTERNAL_EXPORT bool AbiGetMainModuleCodeSection(ModuleSectionInfo *msi)
return false;
}

bool AbGetDebuggedImageName(char *buffer)
{
ModuleInfo mod;

if (!AbGetDebuggedModuleInfo(&mod))
return false;

strcpy(buffer, mod.name);
return true;
}

bool AbGetDebuggedModuleInfo(ModuleInfo *modInfo)
{
duint mainModAddr;

mainModAddr = AbGetDebuggedImageBase();

if (!mainModAddr)
return false;

return InfoFromAddr(mainModAddr, modInfo);
}

duint AbGetDebuggedImageBase()
{
duint base = GetMainModuleBase();

if (base)
return base;

base = (duint)GetDebuggedFileBaseAddress();

if (!base)
base = (duint)GetDebuggedDLLBaseAddress();

return base;
}

bool AbHasDebuggingProcess()
{
ModuleInfo mi;

if (DbgIsDebugging())
{
if (GetMainModuleInfo(&mi))
{
return true;
}
else
DBGPRINT("Debugger is in the debugging state but cant get main module info?!");
return AbGetDebuggedModuleInfo(&mi);
}

return false;
Expand All @@ -259,12 +290,6 @@ void AbReleaseResources()
}
}

void AbGetDebuggingProcessName(char *buffer)
{
GetMainModuleName(buffer);
}


bool AbLoadAvailableModuleAPIs(bool onlyImportsByExe)
{
ListInfo moduleList = { 0 };
Expand Down Expand Up @@ -354,7 +379,7 @@ bool AbLoadAvailableModuleAPIs(bool onlyImportsByExe)

success = true;

GetMainModuleInfo(&AbpCurrentMainModule);
AbGetDebuggedModuleInfo(&AbpCurrentMainModule);

if (AbGetSettings()->exposeDynamicApiLoads)
AbiDetectAPIsUsingByGetProcAddress();
Expand Down
8 changes: 2 additions & 6 deletions x64dbgApiBreak/src/callfind.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <corelib.h>

INTERNAL duint AbpGetActualDataAddress(BASIC_INSTRUCTION_INFO *inst);

FORWARDED int AbiSearchCallersForAFI(duint codeBase, duint codeSize, ApiFunctionInfo *afi)
{
Expand All @@ -23,12 +24,7 @@ FORWARDED int AbiSearchCallersForAFI(duint codeBase, duint codeSize, ApiFunction

if (inst.call || inst.branch)
{
callAddr = 0;

if (inst.type == TYPE_ADDR)
callAddr = inst.value.value;
else if (inst.type == TYPE_MEMORY)
DbgMemRead(inst.memory.value, &callAddr, inst.memory.size);
callAddr = AbpGetActualDataAddress(&inst);

//Gotcha!
if (afi->ownerModule->baseAddr + afi->rva == callAddr)
Expand Down
102 changes: 77 additions & 25 deletions x64dbgApiBreak/src/dynapidetect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ bool AbpParseLoadInstruction(char *inst,LoadInstInfo *linst)
return true;
}

duint AbpGetActualDataAddress(BASIC_INSTRUCTION_INFO *inst)
INTERNAL_EXPORT duint AbpGetActualDataAddress(BASIC_INSTRUCTION_INFO *inst)
{
if (inst->type == TYPE_ADDR)
return inst->value.value;
Expand Down Expand Up @@ -459,7 +459,7 @@ bool AbpExposeStringArgument(short argNumber, char *buf)
return AbpGetApiStringFromProcLoader(argNumber, buf);
}

bool AbpIsValidApi(const char *module, const char *function)
bool AbpIsValidApi(const char *module, const char *function, duint *rva)
{
PBYTE mod = NULL;
PIMAGE_NT_HEADERS ntHdr;
Expand All @@ -468,7 +468,8 @@ bool AbpIsValidApi(const char *module, const char *function)
DWORD moduleSize, exportTableVa;
HANDLE moduleFile, mapping;
char *exportName;
ULONG *addressOfNameStrings;
ULONG *addressOfNameStrings, *addressOfFunctions;
WORD *addressOfOrd;
duint imageBase;

bool valid = false;
Expand Down Expand Up @@ -545,13 +546,21 @@ bool AbpIsValidApi(const char *module, const char *function)
exportTableVa = ntHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
ped = (PIMAGE_EXPORT_DIRECTORY)(exportTableVa + imageBase);
addressOfNameStrings = (ULONG *)(ped->AddressOfNames + imageBase);

for (int i = 0;i < ped->NumberOfNames;i++)
{
exportName = (char *)(imageBase + addressOfNameStrings[i]);

if (!strcmp(exportName, function))
{
if (rva != NULL)
{
addressOfFunctions = (ULONG *)(ped->AddressOfFunctions + imageBase);
addressOfOrd = (WORD *)(ped->AddressOfNameOrdinals + imageBase);

*rva = (duint)(addressOfFunctions[addressOfOrd[i]]);
}

valid = true;
break;
}
Expand All @@ -566,29 +575,51 @@ bool AbpIsValidApi(const char *module, const char *function)
return valid;
}

duint AbpGetCallDestinationAddress(BASIC_INSTRUCTION_INFO *inst)
{
duint callAddr = 0;

if ((inst->type & TYPE_ADDR) || (inst->type & TYPE_VALUE))
callAddr = inst->value.value;
else if (inst->type == TYPE_MEMORY)
DbgMemRead(inst->memory.value, &callAddr, inst->memory.size);

return callAddr;
}

bool AbpIsAPICall2(duint code, ApiFunctionInfo *afi, BASIC_INSTRUCTION_INFO *inst, bool cacheInstruction)
{
duint callAddr;

duint callAddr, trambolineAddr;

BASIC_INSTRUCTION_INFO destInst;

if (inst->call && inst->branch)
{
callAddr = 0;

if (inst->type == TYPE_ADDR)
callAddr = inst->value.value;
else if (inst->type == TYPE_MEMORY)
{
if (sizeof(duint) < inst->memory.size)
DBGPRINT("Integer overflow. What do you to do?");
else
DbgMemRead(inst->memory.value, &callAddr, inst->memory.size);
}
callAddr = AbpGetCallDestinationAddress(inst);

if (callAddr == afi->ownerModule->baseAddr + afi->rva)
{
DBGPRINT("'%s' call found at %p",afi->name, code);
return true;
}
else
{
DbgDisasmFastAt(callAddr, &destInst);

//We looking for only jmp. Eliminate other conditional jumps
if (!destInst.call && destInst.branch && HlpBeginsWithA(destInst.instruction,"jmp",FALSE,3))
{
trambolineAddr = AbpGetCallDestinationAddress(&destInst);

if (trambolineAddr == afi->ownerModule->baseAddr + afi->rva)
{
DBGPRINT("Indirect call (Tramboline) found for %s at 0x%p from 0x%p",
afi->name, callAddr, trambolineAddr);

return true;
}
}
}
}

if (cacheInstruction)
Expand Down Expand Up @@ -640,7 +671,7 @@ bool AbpRegisterAPI(char *module, char *api)
return true;
}

if (!AbpIsValidApi(module, api))
if (!AbpIsValidApi(module, api,NULL))
{
DBGPRINT("Not valid api");
return false;
Expand All @@ -655,24 +686,45 @@ INTERNAL_EXPORT void AbiRaiseOnDemandLoader(const char *dllName, duint base)
ondemand_api_list::iterator modIter;
vector<char *> *apiList;

DBGPRINT("%s loaded looking for its one of the deferred module",dllName);


modIter = AbpDeferList.find(string(dllName));

if (modIter == AbpDeferList.end())
{
DBGPRINT("No, its not");
return;
}

apiList = modIter->second;

DBGPRINT("Deferred api's are now registering.");

for (vector<char *>::iterator it = apiList->begin(); it != apiList->end(); it++)
{
//TODO: Find a way to get remote proc address in DLLLOAD callback

//Probably returns null ?
funcAddr = Script::Misc::RemoteGetProcAddress(dllName, *it);

if (!funcAddr)
{
//And also it may returns null
funcAddr = (duint)ImporterGetRemoteAPIAddressEx(dllName, *it);

if (!funcAddr)
{
duint rva=0;

//worst case!
//We know the loaded dll's base address.
//So if I can read rva of the API from the export table
//I can calculate the real API address in the memory.
//Its a bit slower but it works.
if (AbpIsValidApi(dllName, *it, &rva))
{
funcAddr = base + rva;
}

}
}

if (funcAddr > 0)
{
AbiRegisterDynamicApi(dllName, *it, base,funcAddr,funcAddr-base);
Expand Down Expand Up @@ -740,7 +792,6 @@ INTERNAL_EXPORT bool AbiDetectAPIsUsingByGetProcAddress()

DBGPRINT("Scanning range %p - %p", code, end);


while (code < end)
{
DbgDisasmFastAt(code, &inst);
Expand Down Expand Up @@ -823,7 +874,8 @@ INTERNAL_EXPORT bool AbiDetectAPIsUsingByGetProcAddress()
NEXT_INSTR_ADDR(&code, &inst);
}

DBGPRINT("Success. %d API(s) found!", totalFoundApi);
if (totalFoundApi>0)
DBGPRINT("%d dynamic API(s) found!", totalFoundApi);

return true;
}
Expand Down
14 changes: 11 additions & 3 deletions x64dbgApiBreak/src/incl/apibreak.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#ifndef __APIBREAK_H__
#define __APIBREAK_H__


//Disable shitty paranoid warnings
Expand All @@ -17,6 +19,7 @@
#include <pluginsdk/_plugin_types.h>
#include <pluginsdk/_plugins.h>
#include <pluginsdk/TitanEngine/TitanEngine.h>
#include <pluginsdk/_scriptapi_module.h>

#include <unordered_map>
#include <vector>
Expand Down Expand Up @@ -65,13 +68,16 @@ typedef struct __BpCallbackContext
void * user;
}BpCallbackContext;

bool AbGetDebuggedImageName(char *buffer);

bool AbGetDebuggedModuleInfo(Script::Module::ModuleInfo *modInfo);

duint AbGetDebuggedImageBase();

bool AbHasDebuggingProcess();

void AbReleaseResources();

void AbGetDebuggingProcessName(char *buffer);

bool AbLoadAvailableModuleAPIs(bool onlyImportsByExe);

int AbEnumModuleNames(APIMODULE_ENUM_PROC enumProc, void *user);
Expand All @@ -86,4 +92,6 @@ bool AbSetBreakpointEx(const char *module, const char *apiFunction, duint *funcA

bool AbRegisterBpCallback(BpCallbackContext *cbctx);

void AbDeregisterBpCallback(BpCallbackContext *cbctx);
void AbDeregisterBpCallback(BpCallbackContext *cbctx);

#endif // !__APIBREAK_H__
2 changes: 1 addition & 1 deletion x64dbgApiBreak/src/incl/defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

#define AB_VERSION_MAJOR 0
#define AB_VERSION_MINOR 3
#define AB_VERSION_BUILD 18
#define AB_VERSION_BUILD 22

#if _WIN64
#define AB_PLATFORM "x64"
Expand Down
2 changes: 1 addition & 1 deletion x64dbgApiBreak/src/incl/dlgs/MainForm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ class MainForm : public UiWrapper

if (modCount > 0)
{
AbGetDebuggingProcessName(processName);
AbGetDebuggedImageName(processName);

_this->SetControlTextFormatA(IDC_GRPMOD, "Imported modules && APIs by \"%s\"", processName);
_this->EnableControl(IDC_BTNSETBP);
Expand Down
Loading

0 comments on commit 8fca492

Please sign in to comment.