is there a way to rename a function in windbg? similar of using symbol.
For example, we have a function that is identified in windbg as "example+0x14". after reverse engineering, I know this function is making call to a trampoline that will do printf. Now, I want to rename the "example+0x14" to "example-printf".
Doing this is very straightforward in other debuggers like (x64), but I couldn't find a way of doing this in windbg.
eventually, I want to resolve the addresses in the IAT, find their references (trampolines), rename those trampolines and make my debugging easier.
is there a way of doing it?
There is an API with which you can do this. Unfortunately, there isn't a "command" to do it. One could be created very easily from a debugger extension.
The API in question is IDebugSymbols3::AddSyntheticSymbol (https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/dbgeng/nf-dbgeng-idebugsymbols3-addsyntheticsymbol) or the Unicode variant IDebugSymbols3::AddSyntheticSymbolWide (https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/dbgeng/nf-dbgeng-idebugsymbols3-addsyntheticsymbolwide).
You can go much further than this if you want to write a plug-in. There are new target composition APIs to the debugger (https://www.nuget.org/packages/Microsoft.Debugging.TargetModel.SDK) which allow you to define your own notion of what symbols are by providing a symbol provider (DEBUG_SERVICE_SYMBOL_PROVIDER / ISvcSymbolProvider). The only sample (https://github.com/microsoft/WinDbg-Samples/tree/master/TargetComposition/TextDump) currently available for that API surface unfortunately does not yet cover symbols. In the near future (hopefully within a month or two), there will be a second sample in that same repo which will cover this and allow a whole lot of dynamic manipulation and editing of symbols AND type system.
JFYI: in regard to your comments about the IAT. The ImageInfo.js JavaScript extension which is included with the debugger already parses the IAT and exposes much of that information through the data model. Everything it exposes is on the Contents property of a module object. The IAT information is within .Contents.Imports:
0:007> dx -r3 #$curprocess.Modules[0].Contents.Imports
#$curprocess.Modules[0].Contents.Imports
["KERNEL32.dll"] : KERNEL32.dll
ModuleName : KERNEL32.dll
ResolvedModule : C:\Windows\System32\KERNEL32.DLL
BaseAddress : 0x7ff8eef70000
Name : C:\Windows\System32\KERNEL32.DLL
Size : 0xbd000
Contents
ImageType : PE
Functions
[0x0] : Named Import of 'SetEvent'
[0x1] : Named Import of 'GlobalFree'
[0x2] : Named Import of 'GetLocaleInfoW'
[0x3] : Named Import of 'CreateFileW'
[0x4] : Named Import of 'ReadFile'
...
["GDI32.dll"] : GDI32.dll
ModuleName : GDI32.dll
ResolvedModule : C:\Windows\System32\GDI32.dll
BaseAddress : 0x7ff8f0750000
Name : C:\Windows\System32\GDI32.dll
Size : 0x29000
Contents
ImageType : PE
Functions
[0x0] : Named Import of 'CreateDCW'
[0x1] : Named Import of 'StartPage'
[0x2] : Named Import of 'StartDocW'
[0x3] : Named Import of 'SetAbortProc'
[0x4] : Named Import of 'EndDoc'
...
Related
We have a kernel module using filename_lookup call which is not exported anymore in RHEL8 Kernel 4.18. But found another system call exported in /proc/kallsyms, which is filename_lookup.part.64
What is filename_lookup.part.64 ? Can I call it in our code using the address exported in /proc/kallsyms?
I am not able to find any documentation on filename_lookup.part.64.
Is it safe to use this kind of undocumented APIs?
struct filename filename = { .name = name };
struct nameidata nd;
filename_lookup(AT_FDCWD, &filename, LOOKUP_PARENT, &nd);
I am looking to find the calls that can be used to replace the above in the absence of filename_lookup()
Regarding your question
What is filename_lookup.part.64 ? Can I call it in our code using the
address exported in /proc/kallsyms?
as can be read at here, it is the original filename_lookup function without some parts that the compiler optimized and set them inline, so its not safe.
As said earlier #user3248278, would be easier to use the wrappers such as kern_path or user_path_at_empty.
Filename_lookup is now wrapped with various APIs, which are exported, for example -
*int kern_path(const char *name, unsigned int flags, struct path path) - for getting inodes in kernels.
You can easily search in elixir for filename_lookup and you can find the wrappers.
Related to but not equivalent to DLL Get Symbols From Its Parent (Loader)
Is there a way to convince the Windows loader to resolve a particular symbol referenced by A.dll from either the loading executable or an intermediate dll without specifying the file to resolve symbols from in A.dll?
It's pretty obvious how to do it if the loading .exe has a known name, but if it isn't ...
Here's a good reason why you'd actually want to do this: https://www.gnu.org/software/libc/manual/html_node/Replacing-malloc.html
If this can be done, a good answer would say how to do it some way or another.
I'm half-expecting the answer is it can't be done. In that case, a good answer would show why this is impossible. "The build tools don't support this." is a bad answer.
when we use import we need exactly indicate module name and function name. and we can not use complex algorithms. also for exe not exist well known alias which we can use in place exactly exe name. for compare: in case get GetModuleHandle we can use NULL for get handle to the file used to create the calling process (.exe file). but in case LoadLibraryExW we can not use 0 or empty string (L"") or some another alias for say - we want handle to exe. when loader load our module - he read dll name from IMAGE_IMPORT_DESCRIPTOR and try found or load module with this name first by low level, private, core of LoadLibraryExW. here need exactly name. or load fail. as result use import - not a solution here, if we dont know exe name at build time
possible variant - resolve functions pointers yourself at runtime. here we can get exe HMODULE by GetModuleHandle(0). also if need we can search function not only in exe but somewhere else. can implement any search algorithm.
here exist several ways. for concrete example let we need get pointer to function with signature:
void WINAPI fn(int i);
we can declare pointer to this function and resolve it in runtime
void (WINAPI *fn)(int);
*(void**)&fn = GetProcAddress(GetModuleHandleW(0), "fn");
say on DLL_PROCESS_ATTACH
a slightly different solution (although at the binary level it is completely equivalent) declare function with __declspec(dllimport) attribute. this is for CL.EXE (more known as MSVC) compiler only. so
__declspec(dllimport) void fn(int i);
in this case CL yourself generate pointer to function with name __imp_ ## __FUNCDNAME__ name. so by fact the same as in first variant, when we declare pointer yourself. only difference in syntax and.. symbol name. it will be look like __imp_?fn2##YAXH#Z. problem here that __imp_?fn2##YAXH#Z not valid name for c/c++ - we can not direct assign value to it from c/c++. even if we declare function with extern "C" - function name will be containing # symbol (illegal for c++) for __stdcall and __fastcall functions, for x86. also name will be different for different platforms (x86, x64, etc). for access such names - need or use external asm file (for asm ? and # symbols valid in name) or use /alternatename linker option - for set alias for such name and access symbol via it. say like
__pragma(comment(linker, "/alternatename:__imp_?fn##YAXH#Z=__imp_fn"))
and init via
*(void**)&__imp_fn = GetProcAddress(GetModuleHandle(0), "fn");
another option use __declspec(dllimport) in function declarations + add import library, where all __imp___FUNCDNAME__ (such __imp_?fn2##YAXH#Z) is defined. (even if we have not such library we can easy create it yourself - all what need - correct function declarations with empty implementation). and after we add such import lib to linker input - add /DELAYLOAD:dllname where dllname - exactly name from import lib. sense that this dllname will(can) be not match to exe - all what need - it must be unique. and we need yourself handle delayload (called when we first time call fn). for implement delayload we need implement
extern "C" FARPROC WINAPI __delayLoadHelper2(
PCImgDelayDescr pidd,
FARPROC * ppfnIATEntry
);
we can implement it yourself, or add delayimp.lib to our project. here (in delayimp.lib) the delayLoadHelper2 and implemented. however we must customize this process (default implementation(look in /include/DelayHlp.cpp) will be use LoadLibraryExA with dllname which is not excepted in our case - otherwise we can be simply use import as is). so we need mandatory implement __pfnDliNotifyHook2:
for example:
FARPROC WINAPI MyDliHook(
unsigned dliNotify,
PDelayLoadInfo pdli
)
{
switch (dliNotify)
{
case dliNotePreLoadLibrary:
if (!strcmp(pdli->szDll, "unique_exe_alias"))
{
return (FARPROC)GetModuleHandle(0);
}
}
return 0;
}
const PfnDliHook __pfnDliNotifyHook2 = MyDliHook;
we can look for dliNotePreLoadLibrary notification and instead default LoadLibraryEx(dli.szDll, NULL, 0); use GetModuleHandle(0); for get base of exe.
the "unique_exe_alias" (which linker got from import library) here play role not real exe name, which is unknown, but unique tag(alias) for exe
Calling DLL functions involves the linker generating a stub, unless the function was declared __declspec(dllimport) in which case the stub can be bypassed in favor of an indirect call straight to the import table which is slightly more efficient, e.g.
__declspec(dllimport) void ExitProcess(int);
ExitProcess(0);
generates
call qword ptr [__imp_ExitProcess]
where __imp_ExitProcess resolves to a location in the import table in the executable.
I'm trying to figure out exactly how __imp_ExitProcess is resolved. It occurs as a symbol in kernel32.lib to be sure, but that symbol has storage class IMAGE_SYM_CLASS_EXTERNAL, section number zero and value zero, which amounts to just saying 'this will be defined somewhere else' without actually ever defining it.
Does the __imp_ prefix have special meaning, i.e. does the linker notice that prefix and take it as an instruction to resolve the symbol to the import table entry for the DLL function whose name has that prefix removed? Or is something else going on?
The linker adds to your program a function like:
void (*__imp_ExitProcess)(int) = ...;
void ExitProcess(int n)
{
return (*__imp_ExitProcess)(n);
}
where __imp_ExitProcess points to the "real" ExitProcess in KERNEL32.DLL.
Declaring this in your code:
__declspec(dllimport) void ExitProcess(int);
is equivalent to:
extern void (*__imp_ExitProcess)(int);
#define ExitProcess (*__imp_ExitProcess)
except that __declspec(dllimport) is handled by the compiler, not by the preprocessor.
Just came up with a test that gives a data point. The following program:
__declspec(dllimport) void ExitProcess(int);
void __imp_ExitProcess(int x) {
}
int main() {
ExitProcess(0);
}
crashes when compiled with the Microsoft compiler and run (but runs okay if the empty function is renamed to anything else); thus, it seems the linker behaves as though the __imp_ name is special, at least in the sense that a linker that behaves that way will generate a correct executable in all cases where the Microsoft linker does so, unless I'm missing something.
Members of kernel32.lib are not normal object files but special placeholders. From the PE/COFF spec:
Traditional import libraries, that is, libraries that describe the
exports from one image for use by another, typically follow the layout
described in section 7, “Archive (Library) File Format.” The primary
difference is that import library members contain pseudo-object files
instead of real ones, in which each member includes the section
contributions that are required to build the import tables that are
described in section 6.4, “The .idata Section.” The linker generates
this archive while building the exporting application.
The section contributions for an import can be inferred from a small set of information. The linker can either generate the complete,
verbose information into the import library for each member at the
time of the library’s creation or write only the canonical information
to the library and let the application that later uses it generate the
necessary data on the fly.
[...] a short import library is written as follows:
Archive member header
Import header
Null-terminated import name string
Null-terminated DLL name string
This is sufficient information to accurately reconstruct the entire contents of the member at the time of its use.
In kernel32.lib on my machine, __imp_ExitProcess is mentioned in the first and second linker members (symbol list) and point to the specific pseudo-object describing the import:
Archive member name at 8: /
50107C36 time/date Thu Jul 26 01:07:34 2012
uid
gid
0 mode
106CA size
correct header end
2515 public symbols
[...]
3C874 ExitProcess
3C874 __imp_ExitProcess
[...]
Archive member name at 3C874: KERNEL32.dll/
50107639 time/date Thu Jul 26 00:42:01 2012
uid
gid
0 mode
2D size
correct header end
Version : 0
Machine : 8664 (x64)
TimeDateStamp: 50107639 Thu Jul 26 00:42:01 2012
SizeOfData : 00000019
DLL name : KERNEL32.dll
Symbol name : ExitProcess
Type : code
Name type : name
Hint : 371
Name : ExitProcess
So, as you can see, the data in .lib explicitly says that it refers to an import name ExitProcess from the DLL KERNEL32.dll. The linker can use this to build necessary metadata in the import section.
Now, the above only discussed how the __imp_ExitProcess symbol is resolved. I'm not 100% sure but I think if a symbol (e.g. ExitProcess) has been resolved to such an import stub, and it does not start with __imp_, then the linker has to generate a jump stub (for code symbols), or an indirect access (for data accesses) to the IAT slot.
Can someone please explain me what is a Pseudo Variable and what exactly is the first parameter to the function WinMain below??
GetStartupInfo(&StartupInfo);
int nMainRetVal = WinMain((HINSTANCE)&__ImageBase, NULL, pszCommandLineAnsi,
(StartupInfo.dwFlags & STARTF_USESHOWWINDOW)
? StartupInfo.wShowWindow : SW_SHOWDEFAULT);
Also what does the following statement do??
extern "C" const IMAGE_DOS_HEADER __ImageBase;
The first parameter of WinMain is a so-called "application instance handle". This thing originated from the ancient Windows 3.x times, where it denoted the handle to the running instance of the application. But starting from Win32 (Windows 9x/NT) this parameter is the base address of the executable module mapping in the process virtual address space.
So, what you see is the image base address __ImageBase, which is cast to HINSTANCE to meet the WinMain signature.
Now, __ImageBase - I guess it's a build-time-generated structure that resides exactly at the image starting address.
And, I'm not certain what is a "Pseudo Variable". But perhaps this is exactly __ImageBase.
__ImageBase is the "current module's HINSTANCE from a static library". This is a so called pseudovariable which the linker provides. This pseudovariable is the address where the module has been loaded in memory. Using this pseudovariable you can directly access the mapped image from memory and address its content.
I am trying to write a code which is supposed to print out the names of all the imported dll's in the exe by using the 'name' field of the IMAGE_IMPORT_DESCRIPTOR structure in the .idata section of the exe, but the program seems to be getting stuck in an infinite loop. Can someone please tell me how to get the names printed out correctly...
#include<iostream>
#include<Windows.h>
#include<stdio.h>
#include<WinNT.h>
int main()
{
FILE *fp;
int i;
if((fp = fopen("c:\\Linked List.exe","rb"))==NULL)
std::cout<<"unable to open";
IMAGE_DOS_HEADER imdh;
fread(&imdh,sizeof(imdh),1,fp);
fseek(fp,imdh.e_lfanew,0);
IMAGE_NT_HEADERS imnth;
fread(&imnth,sizeof(imnth),1,fp);
IMAGE_SECTION_HEADER *pimsh;
pimsh = (IMAGE_SECTION_HEADER *)malloc(sizeof(IMAGE_SECTION_HEADER) * imnth.FileHeader.NumberOfSections);
long t;
fread(pimsh,sizeof(IMAGE_SECTION_HEADER),imnth.FileHeader.NumberOfSections,fp);
for(i=0;i<imnth.FileHeader.NumberOfSections;i++)
{
if(!strcmp((char *)pimsh->Name,".idata"))
t = pimsh->PointerToRawData;
pimsh++;
}
fseek(fp,t,0);
IMAGE_IMPORT_DESCRIPTOR iid;
char c;
while(1)
{
fread(&iid,sizeof(iid),1,fp);
if(iid.Characteristics == NULL)
break;
t = ftell(fp);
fseek(fp,(long)iid.Name,0);
while(c=fgetc(fp))
printf("%c",c);
printf("\n");
fseek(fp,t,0);
}
}
There are several problems.
You can't assume the import section is called ".idata". You should locate the imports using IMAGE_OPTIONAL_HEADER.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].
Most offsets within a PE file are Relative Virtual Addresses (RVAs), not file offsets. To convert an RVA to an offset you need to determine which section the virtual address is in, then calculate an offset based on where the section is in the file. Specifically, the IMAGE_IMPORT_DESCRIPTOR.Name field contains an RVA, not a file offset.
Your code will be much simpler (and quicker) if you use a memory-mapped file rather than file I/O.
This MSDN article explains RVAs, the data directory, etc. It also includes pedump, an application with full source code for dumping PE files, which is a useful reference.
The answer by mox is right on all points, however I would also like to add another solution - load the file as an image to read the data.
This is achieved very simply using LoadLibraryEx with just one line of code.
Base = LoadLibraryEx("c:\Linked List.exe", 0, DONT_RESOLVE_DLL_REFERENCES);
This load and maps your executable as an image, so no need for opening/reading/mapping or converting rva to raw offsets.
With the DONT_RESOLVE_DLL_REFERENCES flag the image is uninitialized, so all import data is untouched, and entrypoint code is not executed. The executable is just mapped into memory.
You can simply use Base + Rva to find imported dll name - or any other kind of PE information.
Free the executable image after use with FreeLibrary(Base)