mirror of
https://github.com/x64dbg/x64dbg.git
synced 2024-11-27 14:50:24 +00:00
DBG: more fixes in valapifromstring (this function is getting really complex and confusing now)
This commit is contained in:
parent
a30fecb90b
commit
c17419fc98
@ -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).</P>
|
||||
<P class=rvps3><U>basic calculations</U>: See "Calculations" for more information.</P>
|
||||
<P class=rvps3><U>DLL exports</U>
|
||||
: Type 'GetProcAddress' and it will automatically be
|
||||
<P class=rvps3><U>Module Data</U>:</P>
|
||||
<OL>
|
||||
<LI>
|
||||
<DIV class=rvps3><U>DLL exports</U>:
|
||||
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.</P>
|
||||
<P class=rvps3><U>Loaded Module Bases</U>
|
||||
|
||||
|
||||
|
||||
: 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.</P>
|
||||
<P class=rvps3><U>RVA/File Offset</U>:
|
||||
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.</P>
|
||||
<P class=rvps3><U>Module Entry Points</U> : 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.</P>
|
||||
used.</DIV><U> </U>
|
||||
<LI><U>Loaded Module Bases</U>:
|
||||
If you want to access the loaded module base, you can write: "[module]:0",
|
||||
"[module]:base", "[module]:imagebase" or "[module]:header".
|
||||
<LI><U>RVA/File Offset</U>: 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.
|
||||
<LI><U>Module Entry Points</U>: 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.<BR><BR><STRONG>Notice</STRONG>: 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.</LI></OL>
|
||||
<P class=rvps3><U>labels/symbols</U>:
|
||||
user-defined labels and symbols are a valid expressions.</P>
|
||||
<P class=rvps3><STRONG>Input for arguments can always be done in any of
|
||||
|
@ -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 <modname>: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<uint*> 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
|
||||
|
Loading…
Reference in New Issue
Block a user