DBG: more fixes in valapifromstring (this function is getting really complex and confusing now)

This commit is contained in:
Mr. eXoDia 2014-12-29 02:02:34 +01:00
parent a30fecb90b
commit c17419fc98
2 changed files with 82 additions and 78 deletions

View File

@ -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&nbsp;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&nbsp;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 '?'&nbsp;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&nbsp;are a valid expressions.</P>
<P class=rvps3><STRONG>Input for arguments can always be done in any of

View File

@ -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