Skip to content

Commit c17419f

Browse files
committed
DBG: more fixes in valapifromstring (this function is getting really complex and confusing now)
1 parent a30fecb commit c17419f

File tree

2 files changed

+82
-78
lines changed

2 files changed

+82
-78
lines changed

help/Input.htm

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -49,38 +49,36 @@
4949
the "x" prefix or the "0x" prefix. Decimal numbers can be used by prefixing the
5050
number with a "." (.123=7B).</P>
5151
<P class=rvps3><U>basic calculations</U>: See "Calculations" for more information.</P>
52-
<P class=rvps3><U>DLL exports</U>
53-
: Type 'GetProcAddress' and it will automatically be
52+
<P class=rvps3><U>Module Data</U>:</P>
53+
<OL>
54+
<LI>
55+
<DIV class=rvps3><U>DLL exports</U>:
56+
Type 'GetProcAddress' and it will automatically be
5457
resolved to the actual address of the function.
5558
To explicitly define from which module to load the API, use:
5659
"[module].dll:[api]" or "[module]:[api]". In a similar way you can resolve ordinals, try "[module]:[ordinal]". Another
5760
macro allows you to get the loaded
5861
base of a module. When "[module]" is an empty string (":GetProcAddress" for example), the
5962
module that is currently selected in the CPU will be
60-
used.</P>
61-
<P class=rvps3><U>Loaded Module&nbsp;Bases</U>
62-
63-
64-
65-
: If you want to access the loaded module base,
66-
you can write: "[module]:0", "[module]:base", "[module]:imagebase" or
67-
"[module]:header". You can also use '?' as a delimiter instead of ':'. This is
68-
useful if the module contains an export called "imagebase" for
69-
example.</P>
70-
<P class=rvps3><U>RVA/File Offset</U>:
71-
If you want to access a module RVA you can either write "[module]:0+[rva]" or
72-
you can write "[module]:$[rva]". If you want
73-
to convert a file offset to a VA you can use "[module]:#[offset]". When "[module]" is
74-
an empty string (":0" for example), the module that is currently selected in the CPU will
75-
be used.</P>
76-
<P class=rvps3><U>Module Entry Points</U> : To access a module entry point you can write "[module]:entry",
77-
"[module]:oep" or "[module]:ep". Notice that when there are exports with the
78-
names "entry",
79-
80-
"oep" or
81-
"ep" the address of these will be returned instead. You can also use '?' as
82-
a delimiter instead of ':'. This is useful if the module contains an export called "entry"
83-
for example.</P>
63+
used.</DIV><U> </U>
64+
<LI><U>Loaded Module&nbsp;Bases</U>:
65+
If you want to access the loaded module base, you can write: "[module]:0",
66+
"[module]:base", "[module]:imagebase" or "[module]:header".
67+
<LI><U>RVA/File Offset</U>: If you
68+
want to access a module RVA you can either write "[module]:0+[rva]" or you can
69+
write "[module]:$[rva]". If you want to convert a file offset to a VA you can
70+
use "[module]:#[offset]". When "[module]" is an empty string (":0" for
71+
example), the module that is currently selected in the CPU will be used.
72+
<LI><U>Module Entry Points</U>: To
73+
access a module entry point you can write "[module]:entry", "[module]:oep" or
74+
"[module]:ep". Notice that when there are exports with the names "entry",
75+
"oep" or "ep" the address of these will be returned
76+
instead.<BR><BR><STRONG>Notice</STRONG>: Instead of the ':' delimiter you can
77+
also use a '.' If you need to query module information such as
78+
"[module]:imagebase" or "[module]":entry" you are adviced to
79+
use a '?' as delimiter instead ("[module]?entry"). The '?'&nbsp;does
80+
checking for named exports later, so it will still work when there is an
81+
export called "entry" in the module.</LI></OL>
8482
<P class=rvps3><U>labels/symbols</U>:
8583
user-defined labels and symbols&nbsp;are a valid expressions.</P>
8684
<P class=rvps3><STRONG>Input for arguments can always be done in any of

x64_dbg_dbg/value.cpp

Lines changed: 58 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1169,12 +1169,16 @@ bool valapifromstring(const char* name, uint* value, int* value_size, bool print
11691169
if(!value or !DbgIsDebugging())
11701170
return false;
11711171
//explicit API handling
1172-
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
1172+
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
11731173
bool noexports = false;
1174-
if(!apiname)
1174+
if(!apiname) //not found
11751175
{
1176-
apiname = strstr(name, "?"); //the '?' character cannot be in a path either
1177-
noexports = true;
1176+
apiname = strrchr(name, '.'); //kernel32.GetProcAddress support
1177+
if(!apiname) //not found
1178+
{
1179+
apiname = strchr(name, '?'); //the '?' character cannot be in a path either
1180+
noexports = true;
1181+
}
11781182
}
11791183
if(apiname)
11801184
{
@@ -1204,71 +1208,73 @@ bool valapifromstring(const char* name, uint* value, int* value_size, bool print
12041208
}
12051209
else
12061210
{
1207-
wchar_t* szBaseName = wcschr(szModName, L'\\');
1208-
if(szBaseName)
1211+
HMODULE mod = LoadLibraryExW(szModName, 0, DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE);
1212+
if(!mod)
12091213
{
1210-
szBaseName++;
1211-
HMODULE mod = LoadLibraryExW(szModName, 0, DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE);
1212-
if(!mod)
1213-
{
1214-
if(!silent)
1215-
dprintf("unable to load library %s\n", szBaseName);
1216-
}
1217-
else
1214+
if(!silent)
1215+
dprintf("unable to load library %s\n", szModName);
1216+
}
1217+
else
1218+
{
1219+
uint addr = noexports ? 0 : (uint)GetProcAddress(mod, apiname);
1220+
if(addr) //found exported function
1221+
addr = modbase + (addr - (uint)mod); //correct for loaded base
1222+
else //not found
12181223
{
1219-
uint addr = noexports ? 0 : (uint)GetProcAddress(mod, apiname);
1220-
if(addr) //found exported function
1221-
addr = modbase + (addr - (uint)mod); //correct for loaded base
1222-
else //not found
1224+
if(scmp(apiname, "base") or scmp(apiname, "imagebase") or scmp(apiname, "header")) //get loaded base
1225+
addr = modbase;
1226+
else if(scmp(apiname, "entry") or scmp(apiname, "oep") or scmp(apiname, "ep")) //get entry point
1227+
addr = modbase + GetPE32DataW(szModName, 0, UE_OEP);
1228+
else if(*apiname == '$') //RVA
12231229
{
1224-
if(scmp(apiname, "base") or scmp(apiname, "imagebase") or scmp(apiname, "header")) //get loaded base
1225-
addr = modbase;
1226-
else if(scmp(apiname, "entry") or scmp(apiname, "oep") or scmp(apiname, "ep")) //get entry point
1227-
addr = modbase + GetPE32DataW(szModName, 0, UE_OEP);
1228-
else if(*apiname == '$') //RVA
1229-
{
1230-
uint rva;
1231-
if(valfromstring(apiname + 1, &rva))
1232-
addr = modbase + rva;
1233-
}
1234-
else if(*apiname == '#') //File Offset
1230+
uint rva;
1231+
if(valfromstring(apiname + 1, &rva))
1232+
addr = modbase + rva;
1233+
}
1234+
else if(*apiname == '#') //File Offset
1235+
{
1236+
uint offset;
1237+
if(valfromstring(apiname + 1, &offset))
1238+
addr = valfileoffsettova(modname, offset);
1239+
}
1240+
else
1241+
{
1242+
if(noexports) //get the exported functions with the '?' delimiter
12351243
{
1236-
uint offset;
1237-
if(valfromstring(apiname + 1, &offset))
1238-
addr = valfileoffsettova(modname, offset);
1244+
addr = (uint)GetProcAddress(mod, apiname);
1245+
if(addr) //found exported function
1246+
addr = modbase + (addr - (uint)mod); //correct for loaded base
12391247
}
12401248
else
12411249
{
12421250
uint ordinal;
12431251
if(valfromstring(apiname, &ordinal))
12441252
{
1245-
addr = noexports ? 0 : (uint)GetProcAddress(mod, (LPCSTR)(ordinal & 0xFFFF));
1253+
addr = (uint)GetProcAddress(mod, (LPCSTR)(ordinal & 0xFFFF));
12461254
if(addr) //found exported function
12471255
addr = modbase + (addr - (uint)mod); //correct for loaded base
12481256
else if(!ordinal) //support for getting the image base using <modname>:0
12491257
addr = modbase;
12501258
}
12511259
}
12521260
}
1253-
FreeLibrary(mod);
1254-
if(addr) //found!
1255-
{
1256-
if(value_size)
1257-
*value_size = sizeof(uint);
1258-
if(hexonly)
1259-
*hexonly = true;
1260-
*value = addr;
1261-
return true;
1262-
}
1261+
}
1262+
FreeLibrary(mod);
1263+
if(addr) //found!
1264+
{
1265+
if(value_size)
1266+
*value_size = sizeof(uint);
1267+
if(hexonly)
1268+
*hexonly = true;
1269+
*value = addr;
1270+
return true;
12631271
}
12641272
}
1265-
else if(!silent)
1266-
dputs("unknown error");
12671273
}
12681274
return false;
12691275
}
12701276
int found = 0;
1271-
int kernelbase = -1;
1277+
int kernel32 = -1;
12721278
DWORD cbNeeded = 0;
12731279
Memory<uint*> addrfound;
12741280
if(EnumProcessModules(fdProcessInfo->hProcess, 0, 0, &cbNeeded))
@@ -1282,7 +1288,7 @@ bool valapifromstring(const char* name, uint* value, int* value_size, bool print
12821288
wchar_t szModuleName[MAX_PATH] = L"";
12831289
if(GetModuleFileNameExW(fdProcessInfo->hProcess, hMods[i], szModuleName, MAX_PATH))
12841290
{
1285-
wchar_t* szBaseName = wcschr(szModuleName, L'\\');
1291+
wchar_t* szBaseName = wcsrchr(szModuleName, L'\\');
12861292
if(szBaseName)
12871293
{
12881294
szBaseName++;
@@ -1292,8 +1298,8 @@ bool valapifromstring(const char* name, uint* value, int* value_size, bool print
12921298
ULONG_PTR funcAddress = (ULONG_PTR)GetProcAddress(hModule, name);
12931299
if(funcAddress)
12941300
{
1295-
if(!_wcsicmp(szBaseName, L"kernelbase.dll"))
1296-
kernelbase = found;
1301+
if(!_wcsicmp(szBaseName, L"kernel32.dll"))
1302+
kernel32 = found;
12971303
uint rva = funcAddress - (uint)hModule;
12981304
addrfound[found] = (uint)hMods[i] + rva;
12991305
found++;
@@ -1311,13 +1317,13 @@ bool valapifromstring(const char* name, uint* value, int* value_size, bool print
13111317
*value_size = sizeof(uint);
13121318
if(hexonly)
13131319
*hexonly = true;
1314-
if(kernelbase != -1)
1320+
if(kernel32 != -1) //prioritize kernel32 exports
13151321
{
1316-
*value = addrfound[kernelbase];
1322+
*value = addrfound[kernel32];
13171323
if(!printall or silent)
13181324
return true;
13191325
for(int i = 0; i < found; i++)
1320-
if(i != kernelbase)
1326+
if(i != kernel32)
13211327
dprintf(fhex"\n", addrfound[i]);
13221328
}
13231329
else

0 commit comments

Comments
 (0)