I was reading up on various things on CodeProject and I found this article: http://www.codeproject.com/Articles/29527/Reverse-Engineering-and-Function-Calling-by-Addres
So what I did was I created an injector and a DLL, and grabbed the sample executable file. It basically outputs this when you press F11:
http://i.stack.imgur.com/YIygV.jpg
So I followed the entire tutorial, but the thing is that the address used in the DLL is always changing. This one to be specific:
pFunctionAddress pMySecretFunction = (pFunctionAddress)(0x004113C0);
In his tutorial the address for the function is 0x004113C0. In mine it is something else, and I take the one I have and use it. It works perfectly, but when I close the executable and open it, it won't work anymore, and OllyDbg shows that the address is a totally new one.
So I researched a bit and I started adding breakpoints with OllyDbg. I found out that the address is always going to be:
main + 4C
Where I guess "main" is the main module of these executable. How can I find this address to the function always? Because it changes all the time and I am clueless at this point. In this article I read it doesn't go through what happens when the executable is re-opened, and I've spent 5 hours trying to find a solution.
Thanks in advance!
EDIT:
Huge thanks to everyone. Thanks to mfc especially, I have finally figured it out! What I ended up doing was whenever I hit DLL_PROCESS_ATTACH, I set a global HMODULE to the address of the executable, like this:
HMODULE g_hExeModule;
g_hExeModule = GetModuleHandle(L"TutExample.exe");
And after a few tests it seems like the function address is always the address of the executable + 0x11014, so in the call I just do:
pFunctionAddress pMySecretFunction = (pFunctionAddress)((DWORD)g_hExeModule + 0x11014);
so if I find a way to get the address of "main" I can add a 4C offset and the function will always be there, I think
Again, functions do have an address:
void *(funcPtr)() = (void (*)())((char *)&main + 0x4C);
// If you were right, and you also substituted the appropriate
// function signature above, then this should work:
funcPtr();
The function that you are trying to call is inside of the exe file, so the reference offset should be relative to the memory address that the exe is loaded.
The offset to the target function should be a constant, changed only after each compilation of the source code.
To find out more about your exe, add these two line into your exe:
printf(_T("Exe loaded at: %08X"), GetModuleHandle(_T("TutExample.exe")));
printf(_T("Target function at: %08X"), mySecretFunction);
I cannot edit my post nor add any remark, so I have to post this as a new answer.
Your result:
Exe loaded at: 00000000 (wrong, probably: 00BE0000 and offset is: 00001005)
Target function at: 00BE1005
Exe loaded at: 00000000 (wrong, probably: 01230000 and offset is: 00001005)
Target function at: 01231005
Exe loaded at: 00000000 (wrong, probably: 012A0000 and offset is: 00001005)
Target function at: 012A1005
Please check the name of your compiled exe, is it "TutExample.exe" ? if not, change it to the exact name in the call to GetModuleHandle.
The value of "00000000" indicates that the GetModuleHandle fails because the name "TutExample.exe" is not found in the current memory space.
The address of target function seems ok. Just minus this address with the address of loaded exe and you will get the offset inside the exe memory layout.
You can do this same math inside your injected dll to alway tracks the target function address correctly no matter how the os loads the exe.
Newer OS's have a feature called ASLR (Address space layout randomization). Criminals use some of the trick you are using. So to make bad guys lives more difficult, EXE and DLL's get assigned a different address every time you run a program.
If you compiled the DLL, there is an option to disable ASLR for your DLL.
Related
I just succeeded in adding a section and some code to a pe file (in this case my proxy.exe) in Windows 10. I also changed the entrypoint to the beginning of my new section. When i run the patched .exe my stub gets called and i hear a high frequency Beep (i tested with a beep first), so far so good.
But now i want to return to the OEP. But how can i calculate the address my oep will have in memory?
I thought about that problem and i came up with a ?solution?:
Count the Rsize of all sections except the one i freshly added, then i get the address of my stub in memory (delta offset) and subtract the total section size from it. Now i should be at the beginning of the .text section in memory. Afterwards i add the offset for the oep and thats it.
Will that way work or did i make a mistake?Is there another, probably easier way? And what about dlls, is there a difference for the whole procedure?
http://i.imgur.com/tpUH8x4.png <- Picture of stub
Much thanks in advance! ;)
With OEP I guess you imply fixing IMAGE_OPTIONAL_HEADER. AddressOfEntryPoint.
Ok if I have got it correctly, then you will take the IP -> subtract the offset with the expected RVA (related virtual address) to get the loaded address of the module and add it to the OEP's RVA to get the real address of the entry point.
If you do the maths right this should work.
I dont have commenting privileges yet I think it should go in as a comment rather than answer as I havent tried exactly this thing but it is a proposal, which is similar to what a compiler will do for the binary.
OEP is an RVA, during injection you have the ORIG_RVA and the injected_RVA that you have substituted. In your injection logic just add
offset:push orig_rva.
Then for the offset add a relocation entry in the PE's relocation table. The loader will do the rest.
I have a dump file which I managed to create, from my DLL which is created for any unhandled exception.
When I did something like int* tt = new int[4]; return int[n]; with n = 4, I would get the dump file, and could open it, and see at what line the error is caused. This was possible for both directly from a release exe, and a release DLL.
Now this was an easy error, and I only entered it to test my memory dump creation.
I now have a 900kb dump file, and the event log says the error comes from my .DLL, yet if I open the file, it does not display any source code.
The call stack is
KERNELBASE.dll!RaiseException() + 0x3d bytes
clr.dll!RaiseTheExceptionInternalOnly() + 0x18f bytes
clr.dll!IL_Throw() + 0xe2 bytes
000007fe81f65fd7()
00000000034d1610()
000000002d06ecb8()
436f93ce00050011()
436f93cf00110012()
000000002d06ec50()
00006d930c4f7680()
clr.dll!InlinedCallFrame::`vftable'()
000000002d06f3d8()
which does not help me at all to figure out where in the DLL my error is coming from.
Another issue with debugging this is, it only happens on a live-PC, but never on my debugging system. Can anyone help me finding a way how to debug this? It seems to happen on the calling of the DLL, but: not every time, only like every 2nd time (sometimes on 1st try, sometimes on 5th). I am completely lost on what is happening here.
Edit:
Updated the call stack with the Microsoft symbols loaded, but I still do not know where this may be coming from.
You need to load the symbols for kernelbase.dll. And possibly clr.dll.
Presumably you are using visual studio?
Set it up to access symbols from the microsoft symbol server: http://msdn.microsoft.com/en-us/library/b8ttk8zy(v=vs.80).aspx
You may need to right click on items in the callstack and tell it to load symbols.
Additionally be sure to keep a copy of the pdb file for any releases of software you make.
Im starting a protector/packer/binder like project.
the goal is when you have a full app directory with
/images/
/music/
base *.ini files
dlls
exes
you just use packer.exe on it and all these files are packed, encrypted, and stored in the resulting exe.
the resulting exe then creates a transparent virtual filesystem that falls back to the "real" one if a file is not found.
i allready can handle (not very accurately) loading dlls from memory, etc but i have a problem with the hmm hooks..
for now, as a ProofOfConcept im attaching a debbuger (written in c++) to a target.exe
it looks somewhat like
======= Started [target.exe] =======
> Placing breakpoint on EP : 0x401130
Process started
Loaded module : [target.exe]
Loaded module : [ntdll.dll]
Loaded module : [kernel32.dll]
[...]
Break point at [0x401130]
> Restored EP byte.
Loaded module : [bass.dll]
Break point at [0x760fcc4e]
Found set bp : kernel32!CreateFileW
[!] CreateFileW Callback Function :
FileName : C:\Users\user\Desktop\cppve\loader\bin\Debug\target.exe
Access : 0x80000000
Return Addr: 0x741b91e6
> Re-setting bp at [0x760fcc4e]
Break point at [0x760fcc4e]
Found set bp : kernel32!CreateFileW
[!] CreateFileW Callback Function :
FileName : .\beyond_v.mod
Access : 0x80000000
Return Addr: 0x760fcfa0
i am handling breakpoints in the debugger for things like CreateFileW ReadFile etc
im having problems in supplying the target with useable data.
should i create a fake handle and then catch it and process it ? or are there too many things that can go very wrong with that approach ?
here is a sample callback function for CreateFileW
void callback_createfilew(CONTEXT* ct){
//stub
cout<<"[!] CreateFileW Callback Function :"<<endl;
void* returnaddr=MemReadDwordPtr(hProcess,(void*)ct->Esp);
string fn=MemReadCString(hProcess,MemReadDwordPtr(hProcess,(void*)ct->Esp+4),true);
void* access=MemReadDwordPtr(hProcess,(void*)ct->Esp+8);
void* sharemode=MemReadDwordPtr(hProcess,(void*)ct->Esp+12);
void* dwCreationDisposition=MemReadDwordPtr(hProcess,(void*)ct->Esp+20);
void* dwFlagsAndAttributes=MemReadDwordPtr(hProcess,(void*)ct->Esp+24);
cout<<" FileName : "<<fn<<endl;
cout<<" Access : "<<(void*)access<<endl;
cout<<" Return Addr: "<<(void*)returnaddr<<endl;
if(fn.compare(".\\beyond_v.mod")==0){
// this is wrong, we need to call it from the target process...
HANDLE ret=CreateFileA(".\\_beyond_v.mod",(DWORD)access,(DWORD)sharemode,NULL,(DWORD)dwCreationDisposition,(DWORD)dwFlagsAndAttributes,NULL);
ct->Esp+=0x20;
ct->Eax=(DWORD)ret;
ct->Eip=(DWORD)returnaddr;
}
should i make a codecave in the process and push shellcodes [ Edit: sorry, i use many of these words to describe different things but i think you will catch what i ment :) ] there to execute my faking code ?
or maybe inject a dll that will handle int3s and pass control to it via exception handlers set up by the loader ? however that can proove to be tricky... that dll would have to be in the virtual filesystem ! so i would have to hand-load it before any other initialisation takes place.
i would like, in the final version, to completly drop the debugger. it will only cause problems and seriously comprimise the protector part of the project.
If you want your "packer" to operate transparently on precompiled binaries and want everything to be inside the resultant single binary, the packer needs to add the hooking code to the binary, perhaps making it execute as the very first thing and only then pass control to the original entry point of the binary. This isn't very trivial, although is certainly doable.
But you have another problem here. This hooking code will contain the decryption code and probably the key as well and this all thing is breakable by a good programmer with a debugger and some other tools.
As for fake handles, I'd see if it's possible to open a file multiple times and get different handles. If it is, just open any existing file for reading in a shared mode, remember the handle and use it for an in-memory file. Need another handle? Open the file again to get one. That will guarantee no collision with other real handles.
I'm trying to get symbols from addresses I got from my stack, but SymFromAddr keeps failing with system error 126 (The specified module could not be found.)
I'm initializing the symboling thing with
SymInitialize(m_processHandle, NULL, TRUE);
(the last parameter == true ==> It loads the PDB automatically)
and I use SymFromAddr like this:
SYMBOL_INFO_PACKAGE sym = { sizeof(sym) };
sym.si.MaxNameLen = MAX_SYM_NAME;
DWORD64 displacement = 0;
bool ok = SymFromAddr(m_processHandle, address, &displacement, &sym.si);
The code is in C++ on windows.
and the PDB FILE IS IN THE DIRECTORY OF THE EXE!
What am I doing wrong?
thanks :)
SymFromAddr is a little bit capricious.
If any LoadLibrary occur between SymInitialize and SymFromAddr it may not work. If SymFromAddr you can perfom a SymInitialize again (hint: you can cache address to avoid a lot of SymInitialize which is a huge CPU consummer)
64 bits implementation of SymFromAddr (ie. SymFromAddr64) works better
If code is not optimized it'll work better
VC9 generated pdb works better than older version.
You can find some idea in the following code
http://code.google.com/p/nprof/source/browse/0.11/Hook/StackWalker.cpp?r=281
How do I restore the stack trace function name instead of <UNKNOWN>?
Event Type: Error
Event Source: abcd
Event Category: None
Event ID: 16
Date: 1/3/2010
Time: 10:24:10 PM
User: N/A
Computer: CMS01
Description:
Server.exe caused a in module at 2CA001B:77E4BEF7
Build 6.0.0.334
WorkingSetSize: 1291071488 bytes
EAX=02CAF420 EBX=00402C88 ECX=00000000 EDX=7C82860C ESI=02CAF4A8
EDI=02CAFB68 EBP=02CAF470 ESP=02CAF41C EIP=77E4BEF7 FLG=00000206
CS=2CA001B DS=2CA0023 SS=7C820023 ES=2CA0023 FS=7C82003B GS=2CA0000
2CA001B:77E4BEF7 (0xE06D7363 0x00000001 0x00000003 0x02CAF49C)
2CA001B:006DFAC7 (0x02CAF4B8 0x00807F50 0x00760D50 0x007D951C)
2CA001B:006DFC87 (0x00003561 0x7F6A0F38 0x008E7290 0x00021A6F)
2CA001B:0067E4C3 (0x00003561 0x00000000 0x02CAFBB8 0x02CAFB74)
2CA001B:00674CB2 (0x00003561 0x006EBAC7 0x02CAFB68 0x02CAFA64)
2CA001B:00402CA4 (0x00003560 0x00000000 0x00000000 0x02CAFBB8)
2CA001B:00402B29 (0x00003560 0x00000001 0x02CAFBB8 0x00000000)
2CA001B:00683096 (0x00003560 0x563DDDB6 0x00000000 0x02CAFC18)
2CA001B:00688E32 (0x02CAFC58 0x7C7BE590 0x00000000 0x00000000)
2CA001B:00689F0C (0x02CAFC58 0x7C7BE590 0x00000000 0x00650930)
2CA001B:0042E8EA (0x7F677648 0x7F677648 0x00CAFD6C 0x02CAFD6C)
2CA001B:004100CA (0x563DDB3E 0x00000000 0x00000000 0x008E7290)
2CA001B:0063AC39 (0x7F677648 0x02CAFD94 0x02CAFD88 0x77B5B540)
2CA001B:0064CB51 (0x7F660288 0x563DD9FE 0x00000000 0x00000000)
2CA001B:0063A648 (0x00000000 0x02CAFFEC 0x77E6482F 0x008E7290)
2CA001B:0063A74D (0x008E7290 0x00000000 0x00000000 0x008E7290)
2CA001B:77E6482F (0x0063A740 0x008E7290 0x00000000 0x00000000)
Get the exact same build of the program, objdump it, and have a look at what function is at the address. If symbol names have been stripped from the executable, this might be a little bit difficult.
If the program code is in any way dynamic, you may have to run it into a debugger to find the addresses of functions.
If the program is deliberately obfuscated and nasty, and it randomises its function addresses in some way at runtime (evasive things like viruses, or copy-protection code sometimes do this) then all bets are off.
In general:
The easiest way to find out what caused the crash is to follow the steps necessary to reproduce it in an instance of the application running in a debugger. All other approaches are much more difficult. This is why developers will often not spend time trying to tackle bugs which there are no known methods to reproduce.
You need to have the debug info file (.pdb) next to the exe when the crash occurs.
Then hopefully, your crash dumping code can load it and use the information in it.
Try to run the same built from your IDE, pause it and jump to the adresses in assembly. Then you can switch to source code and see the functions there.
At least that's how it works in Delphi. And I know of this possibility in Visual Studio as well.
If you don't have the built in your IDE, you have to use a Debugger like OllyDbg. Run the exe that caused the errors and pause the application in OllyDbg. Go to the adresses from the stack trace.
Open a similar application project in your IDE, run it and pause it. Search for the same binary pattern you see in OllyDbg and then switch to source code.
The last possibility I know is analysing the map file if you built it during your built.
I use StackWalker - just compile it into the source of your program, and if it crashes you can generate a stack trace at that time, including function names.
The most common cause is that you in fact don't have a module at the specified address. This can happen e.g. when you dereference an uninitialized function pointer, or call a virtual function using an invalid this pointer.
This is probably not the case here: "77E4BEF7" is with very high probability a Windows DLL, and 006DFAC7 an address in one of your modules. You don't need PDB files for this: Windows should always know the module name (.EXE or .DLL) - in fact, it needs first that module name to even find the proper PDB file.
Now, the remaining question is why you don't have the module information. This I can't tell from the information above. You need information about the actual system. For instance, does if have DEP? Is DEP enabled for your process?