From c17419fc98cbe80ebd391f1f463c63dce2258ce2 Mon Sep 17 00:00:00 2001 From: "Mr. eXoDia" Date: Mon, 29 Dec 2014 02:02:34 +0100 Subject: [PATCH] DBG: more fixes in valapifromstring (this function is getting really complex and confusing now) --- help/Input.htm | 50 +++++++++---------- x64_dbg_dbg/value.cpp | 110 ++++++++++++++++++++++-------------------- 2 files changed, 82 insertions(+), 78 deletions(-) diff --git a/help/Input.htm b/help/Input.htm index 677d0b62..e1fdfb54 100644 --- a/help/Input.htm +++ b/help/Input.htm @@ -49,38 +49,36 @@ numbers are interpreted as hex by default. If you want to be sure, you can use the "x" prefix or the "0x" prefix. Decimal numbers can be used by prefixing the number with a "." (.123=7B).

basic calculations: See "Calculations" for more information.

-

DLL exports - : Type 'GetProcAddress' and it will automatically be +

Module Data:

+
    +
  1. +
    DLL exports: + Type 'GetProcAddress' and it will automatically be resolved to the actual address of the function. To explicitly define from which module to load the API, use: "[module].dll:[api]" or "[module]:[api]". In a similar way you can resolve ordinals, try "[module]:[ordinal]". Another macro allows you to get the loaded base of a module. When "[module]" is an empty string (":GetProcAddress" for example), the module that is currently selected in the CPU will be -used.

    -

    Loaded Module Bases - - - - : If you want to access the loaded module base, -you can write: "[module]:0", "[module]:base", "[module]:imagebase" or -"[module]:header". You can also use '?' as a delimiter instead of ':'. This is -useful if the module contains an export called "imagebase" for -example.

    -

    RVA/File Offset: -If you want to access a module RVA you can either write "[module]:0+[rva]" or -you can write "[module]:$[rva]". If you want -to convert a file offset to a VA you can use "[module]:#[offset]". When "[module]" is -an empty string (":0" for example), the module that is currently selected in the CPU will -be used.

    -

    Module Entry Points : To access a module entry point you can write "[module]:entry", -"[module]:oep" or "[module]:ep". Notice that when there are exports with the -names "entry", - - "oep" or -"ep" the address of these will be returned instead. You can also use '?' as -a delimiter instead of ':'. This is useful if the module contains an export called "entry" -for example.

    +used.
    +
  2. Loaded Module Bases: + If you want to access the loaded module base, you can write: "[module]:0", + "[module]:base", "[module]:imagebase" or "[module]:header". +
  3. RVA/File Offset: If you + want to access a module RVA you can either write "[module]:0+[rva]" or you can + write "[module]:$[rva]". If you want to convert a file offset to a VA you can + use "[module]:#[offset]". When "[module]" is an empty string (":0" for + example), the module that is currently selected in the CPU will be used. +
  4. Module Entry Points: To + access a module entry point you can write "[module]:entry", "[module]:oep" or + "[module]:ep". Notice that when there are exports with the names "entry", + "oep" or "ep" the address of these will be returned + instead.

    Notice: Instead of the ':' delimiter you can + also use a '.' If you need to query module information such as + "[module]:imagebase" or "[module]":entry" you are adviced to + use a '?' as delimiter instead ("[module]?entry"). The '?' does + checking for named exports later, so it will still work when there is an + export called "entry" in the module.

labels/symbols: user-defined labels and symbols are a valid expressions.

Input for arguments can always be done in any of diff --git a/x64_dbg_dbg/value.cpp b/x64_dbg_dbg/value.cpp index ed5a1754..918d454f 100644 --- a/x64_dbg_dbg/value.cpp +++ b/x64_dbg_dbg/value.cpp @@ -1169,12 +1169,16 @@ bool valapifromstring(const char* name, uint* value, int* value_size, bool print if(!value or !DbgIsDebugging()) return false; //explicit API handling - const char* apiname = strstr(name, ":"); //the ':' character cannot be in a path: http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx#naming_conventions + const char* apiname = strchr(name, ':'); //the ':' character cannot be in a path: http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx#naming_conventions bool noexports = false; - if(!apiname) + if(!apiname) //not found { - apiname = strstr(name, "?"); //the '?' character cannot be in a path either - noexports = true; + apiname = strrchr(name, '.'); //kernel32.GetProcAddress support + if(!apiname) //not found + { + apiname = strchr(name, '?'); //the '?' character cannot be in a path either + noexports = true; + } } if(apiname) { @@ -1204,45 +1208,49 @@ bool valapifromstring(const char* name, uint* value, int* value_size, bool print } else { - wchar_t* szBaseName = wcschr(szModName, L'\\'); - if(szBaseName) + HMODULE mod = LoadLibraryExW(szModName, 0, DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE); + if(!mod) { - szBaseName++; - HMODULE mod = LoadLibraryExW(szModName, 0, DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE); - if(!mod) + if(!silent) + dprintf("unable to load library %s\n", szModName); + } + else + { + uint addr = noexports ? 0 : (uint)GetProcAddress(mod, apiname); + if(addr) //found exported function + addr = modbase + (addr - (uint)mod); //correct for loaded base + else //not found { - if(!silent) - dprintf("unable to load library %s\n", szBaseName); - } - else - { - uint addr = noexports ? 0 : (uint)GetProcAddress(mod, apiname); - if(addr) //found exported function - addr = modbase + (addr - (uint)mod); //correct for loaded base - else //not found + if(scmp(apiname, "base") or scmp(apiname, "imagebase") or scmp(apiname, "header")) //get loaded base + addr = modbase; + else if(scmp(apiname, "entry") or scmp(apiname, "oep") or scmp(apiname, "ep")) //get entry point + addr = modbase + GetPE32DataW(szModName, 0, UE_OEP); + else if(*apiname == '$') //RVA { - if(scmp(apiname, "base") or scmp(apiname, "imagebase") or scmp(apiname, "header")) //get loaded base - addr = modbase; - else if(scmp(apiname, "entry") or scmp(apiname, "oep") or scmp(apiname, "ep")) //get entry point - addr = modbase + GetPE32DataW(szModName, 0, UE_OEP); - else if(*apiname == '$') //RVA + uint rva; + if(valfromstring(apiname + 1, &rva)) + addr = modbase + rva; + } + else if(*apiname == '#') //File Offset + { + uint offset; + if(valfromstring(apiname + 1, &offset)) + addr = valfileoffsettova(modname, offset); + } + else + { + if(noexports) //get the exported functions with the '?' delimiter { - uint rva; - if(valfromstring(apiname + 1, &rva)) - addr = modbase + rva; - } - else if(*apiname == '#') //File Offset - { - uint offset; - if(valfromstring(apiname + 1, &offset)) - addr = valfileoffsettova(modname, offset); + addr = (uint)GetProcAddress(mod, apiname); + if(addr) //found exported function + addr = modbase + (addr - (uint)mod); //correct for loaded base } else { uint ordinal; if(valfromstring(apiname, &ordinal)) { - addr = noexports ? 0 : (uint)GetProcAddress(mod, (LPCSTR)(ordinal & 0xFFFF)); + addr = (uint)GetProcAddress(mod, (LPCSTR)(ordinal & 0xFFFF)); if(addr) //found exported function addr = modbase + (addr - (uint)mod); //correct for loaded base else if(!ordinal) //support for getting the image base using :0 @@ -1250,25 +1258,23 @@ bool valapifromstring(const char* name, uint* value, int* value_size, bool print } } } - FreeLibrary(mod); - if(addr) //found! - { - if(value_size) - *value_size = sizeof(uint); - if(hexonly) - *hexonly = true; - *value = addr; - return true; - } + } + FreeLibrary(mod); + if(addr) //found! + { + if(value_size) + *value_size = sizeof(uint); + if(hexonly) + *hexonly = true; + *value = addr; + return true; } } - else if(!silent) - dputs("unknown error"); } return false; } int found = 0; - int kernelbase = -1; + int kernel32 = -1; DWORD cbNeeded = 0; Memory addrfound; if(EnumProcessModules(fdProcessInfo->hProcess, 0, 0, &cbNeeded)) @@ -1282,7 +1288,7 @@ bool valapifromstring(const char* name, uint* value, int* value_size, bool print wchar_t szModuleName[MAX_PATH] = L""; if(GetModuleFileNameExW(fdProcessInfo->hProcess, hMods[i], szModuleName, MAX_PATH)) { - wchar_t* szBaseName = wcschr(szModuleName, L'\\'); + wchar_t* szBaseName = wcsrchr(szModuleName, L'\\'); if(szBaseName) { szBaseName++; @@ -1292,8 +1298,8 @@ bool valapifromstring(const char* name, uint* value, int* value_size, bool print ULONG_PTR funcAddress = (ULONG_PTR)GetProcAddress(hModule, name); if(funcAddress) { - if(!_wcsicmp(szBaseName, L"kernelbase.dll")) - kernelbase = found; + if(!_wcsicmp(szBaseName, L"kernel32.dll")) + kernel32 = found; uint rva = funcAddress - (uint)hModule; addrfound[found] = (uint)hMods[i] + rva; found++; @@ -1311,13 +1317,13 @@ bool valapifromstring(const char* name, uint* value, int* value_size, bool print *value_size = sizeof(uint); if(hexonly) *hexonly = true; - if(kernelbase != -1) + if(kernel32 != -1) //prioritize kernel32 exports { - *value = addrfound[kernelbase]; + *value = addrfound[kernel32]; if(!printall or silent) return true; for(int i = 0; i < found; i++) - if(i != kernelbase) + if(i != kernel32) dprintf(fhex"\n", addrfound[i]); } else