Open ViRb3 opened 2 years ago
I have not tested this project for 32-bit compilation. It should definitely work, but some changes may be necessary.
I tried to get it working the whole day today, I found that the exports for the 32-bit version.dll are missing the GetFileVersionInfoExA and GetFileVersionInfoSizeExA. So some code modification is definitely needed here. Also, for 32-bit to compile the declspec function needs to be modified as asm("jmp *_orig_"#name)
. Despite these changes any program that loads this DLL crashes with access violation. I was trying to catch the crash via ASM debugger, but no luck so far. Any help here would be greatly appreciated
I'd recommend debugging with x64dbg, it will definitely allow you to catch the issue.
I am using IDA Pro Advanced. It does not crash within the library, nor as a result of calling the redirected Exports. I am suspecting perhaps my compiler is causing issues. Is there any specific version, specific flavor you would suggest ?
OK, I did some debugging and I found the problem. Your asm directive instructs to jump to the original function. The compiler however generates some extra opcodes that messes up the stack, especially the return address of the calling routine:
.text:65981428 public __GetFileVersionInfoExW
.text:65981428 __GetFileVersionInfoExW proc near
.text:65981428 push ebp ; <= this directive messes up the stack
.text:65981429 mov ebp, esp
.text:6598142B jmp ds:_orig_GetFileVersionInfoExW
.text:6598142B __GetFileVersionInfoExW endp
.text:6598142B
.text:6598142B ; ---------------------------------------------------------------------------
.text:65981431 align 2
.text:65981432 pop ebp
.text:65981433 retn
The EBP register is zero at addr 0x65981428 , if it gets pushed to stack, this becomes the return address for the _orig_GetFileVersionExW. Once the original routine finishes, it instructs to "return" to the address that has been pushed by EBP register. That address is 0, hence the access violation crash.
I am yet to figure out how to prevent the compiler to generate those push and mov directives. If you have any ideas, let me know
I fixed it as follows:
#define WRAPPER_GENFUNC(name) \
FARPROC orig_##name; \
__declspec(naked) void _##name() \
{ \
asm("pop %ebp; jmp *_orig_"#name); \
}
Not the most elegant way but it works. it produces the following assembly code:
.text:65981438 public __GetFileVersionInfoA
.text:65981438 __GetFileVersionInfoA proc near
.text:65981438 push ebp
.text:65981439 mov ebp, esp
.text:6598143B pop ebp ; <= this instuction negates the "push ebp" created by the compiler
.text:6598143C jmp ds:_orig_GetFileVersionInfoA
.text:6598143C __GetFileVersionInfoA endp
.text:6598143C
Perhaps there is a more elegant way to do it, maybe its just a code optimization settings in the compiler. If you figure it out, let me know. As a temporary solution, the above would work
Any idea how to get this work under 32-bit environment ? I can compile the the project without issues, but any application I launch where this library gets initialized crashes with access violation after I confirm the message box
Originally posted by @iceman-77 in https://github.com/ViRb3/PerfectProxyDLL/issues/2#issuecomment-1058591039