Pancake Posted April 28, 2016 Share Posted April 28, 2016 (edited) Hello. I got my old code with this feature which i wanted to review, and something very strange happens. All the relocations/imports etc are properly resolved but the program crashes when invoking the DllMain. If i run it in olly, everything works fine (and i see MessageBox from process attach). The loader run as administrator hangs inside DllMain not displayin anything, and run without elevated privileges just crashes. When i removed plugins from olly it also hangs like in first case. What may be the cause?? Edit: After checking the dll, the function which causes freeze (when manually mapped) is "dllmain_crt_dispatch" Edit: I am doin some mistake with allocation. After stepping throught entire crt init i noticed, that it hangs inside loop "LOCK CMPXCHG DWORD PTR DS:[ESI],ECX". Normally there are 00 00 00 00 here. In my case, i found "0D F0 AD BA" blocks (which mean something in msvc with allocation). So thats a step forward... Edit: Yeah that was that. Zeroing memory after allocation did the trick. Resolved issue talkin to myself here on forum Maybe someone will find it useful someday. Edited April 28, 2016 by Pancake Link to comment
Pancake Posted May 1, 2016 Author Share Posted May 1, 2016 Hey its me again I got problem with static stuff, for example singleton's constructor is not called in manually mapped file! Im havin trouble fixin this, something with TLS section but i got no idea what should i do with that Link to comment
kao Posted May 1, 2016 Share Posted May 1, 2016 See https://sourceforge.net/p/upx/discussion/6805/thread/b0d51069/ and UPX source in general - search for "TLS" Link to comment
Pancake Posted May 1, 2016 Author Share Posted May 1, 2016 (edited) Im still confused. I read that i have to call the DllMain with DLL_THREAD_ATTACH for every callback before DLL_PROCESS_ATTACH which runs the dll? So how do i pass the callback address to Dllmain? Or do i have to call each tls callback with (hinstance, DLL_THREAD_ATTACH, reserved) arguments? Still, what for are indexes in tls table, and the raw data is not referenced anywhere. The "AddressOfCallBacks" start with 3 zero dwords and then with 3 function addresses, why the zeroes? There is so much i dont understand here Edited May 1, 2016 by Pancake Link to comment
atom0s Posted May 1, 2016 Share Posted May 1, 2016 TLS callbacks should be called with DLL_PROCESS_ATTACH on their first initial call. (Also keep in mind the process/module can have more than one TLS callback.) Link to comment
Pancake Posted May 1, 2016 Author Share Posted May 1, 2016 (edited) But "how" should they be called? Thats my TLS table after fixing relocations and imports. Mapped base 7EF80000 ->TLS Table StartAddressOfRawData: 0x1F000 -> 00 00 00 00 00 00 00 80 EndAddressOfRawData: 0x1F008 AddressOfIndex: 0x1DA94 -> only zero AddressOfCallBacks: 0x15168 -> 00 00 00 00 00 00 00 00 7C AD F8 7E CC 15 F9 7E 69 5C F8 7E 00 00 00 00 SizeOfZeroFill: 0x00000000 Characteristics: 0x00300000 So i see two 0 dwords in the callback table (why zero and not addresses?), then 3 addresses from codesection. I tried calling them with dllbase and dll_thread_attach/dll_process_attach but it crashes. Thats piece of code where the constructor is skipped. MOV EAX,DWORD PTR FS:[0x2C] // this is wrong when mapped manually MOV ECX,DWORD PTR DS:[_tls_index] MOV ECX,DWORD PTR DS:[EAX+ECX*4] MOV EAX,DWORD PTR DS:[0x638933B0] CMP EAX,DWORD PTR DS:[ECX+4] // this cmp behaves differently Edited May 1, 2016 by Pancake Link to comment
atom0s Posted May 1, 2016 Share Posted May 1, 2016 Tls callbacks are called just like DllMain of a DLL. They take 3 params but have no return. In C++ they look like this: void __stdcall TlsCallback(PVOID lpModuleHandle, DWORD fdwReason, PVOID lpContext) { } The first param is the current applications base address, second param is the reason the Tls was called (ie. DLL_PROCESS_ATTACH), and the third is the context / reserved param that is generally not used and can just be null/0. You can see how UPX invokes Tls callbacks here: https://github.com/korczis/upx/blob/be081ef98d4c5b967d203ea0261286d8d2e77449/src/stub/src/i386-win32.pe.S#L226 Link to comment
Pancake Posted May 1, 2016 Author Share Posted May 1, 2016 (edited) Okay i figured out these are NOT tls callbacks causing problems. Its the raw data. I need to call LdrpHandleTlsData routine and it makes the fs:[2c] work and maps the raw data from tls section so everything works fine. But sadly this is not exported by ntdll which makes it not portable, right now im using hardcoded ntdll offset for my OS version The second possibility is to do it manually, allocate memory, copy the static TLS buffer and set in in the PEB like in code below: https://github.com/DarthTon/Blackbone/blob/master/src/BlackBoneDrv/MMap.c#L1280 Edited May 2, 2016 by Pancake Link to comment
mudlord Posted May 4, 2016 Share Posted May 4, 2016 (edited) Is this for something like a exe packer? not sure im following what you are trying to do exactly. trying to load a DLL completely from memory? Edited May 4, 2016 by mudlord Link to comment
A200K Posted May 14, 2016 Share Posted May 14, 2016 (edited) On 4.5.2016 at 11:07 AM, mudlord said: Is this for something like a exe packer? not sure im following what you are trying to do exactly. trying to load a DLL completely from memory? Yes, manual mapping is like calling the windows api func LoadLibrary, but doing all necessary stuff the windows loader would do by yourself, and you don't need to have the dll located on your hard drive. Could be used for a packer, to insert/pack other dlls into an executable file, so you have only one exe file left but you still have the functionality of the dlls. Could be used for other application modification as well, e.g. for game hacking Edited May 14, 2016 by A200K Corrected typo lol Link to comment
Pancake Posted May 14, 2016 Author Share Posted May 14, 2016 Yes just load dll from memory. I never had to use tls because all of my stuff was written in c++ which did not use tls. But in new visual studio the compiler started using fs:[2c] for static things. And so i have to manually call nonexported LdrpHandleTlsData (or something like that, forgot name) but this function is not exported by ntdll and so offset varies on every OS. I dont know how to fix that Link to comment
atom0s Posted May 14, 2016 Share Posted May 14, 2016 1 hour ago, Pancake said: Yes just load dll from memory. I never had to use tls because all of my stuff was written in c++ which did not use tls. But in new visual studio the compiler started using fs:[2c] for static things. And so i have to manually call nonexported LdrpHandleTlsData (or something like that, forgot name) but this function is not exported by ntdll and so offset varies on every OS. I dont know how to fix that 11 There are a few manual mapping examples around the net that have implementations of this you could look into. This is one of the more up to date ones of a manual map implementation that is public: https://github.com/DarthTon/DarkMMap Link to comment
Pancake Posted May 14, 2016 Author Share Posted May 14, 2016 I've seen dark map. He does it this way https://github.com/DarthTon/Blackbone/blob/master/src/BlackBoneDrv/MMap.c#L1280 But in my case, when i manually allocate the memory + set fs:[2c] only MAIN thread has it set. Creating another thread results spoiled fs for new thread... The Ldrp ntdll function works well for child threads tho. Link to comment
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now