Question

I'd like to force a coredump from a program (or see its memory at a specific time in some other way). There are a couple of problems though:

  • I'm running it under wine (cannot run via winedbg, because the application detects it)
  • The application uses exceptions / SEH / other handlers, which capture non-standard events
  • Even attaching strace stops the program from working
  • I'd like to poke around, so there are no specific areas that I could print
  • Well... I don't have the source

I've tried changing the code to both:

xor eax, eax
call eax

and some random stuff which wasn't a real instruction - both time SEH kicked in and rescued the application.

How can I get the information? I need the memory image from a specific time and can patch the exact place where it occurs.

Was it helpful?

Solution

Since you have access to the source code of wine, I'd suggest just altering the wine SEH code, and/or the implementation of the IsDebuggerPresent() function.

Another option would be to modify the application to suspend itself by raising a SIGSTOP signal. Windows applications in Wine can still access linux APIs by invoking int $0x80, so you could inject some code like the following:

mov %eax, $20  ;; sys_getpid
int $0x80
mov %ebx, %eax ;; load pid parameter
mov %eax, $37  ;; sys_kill
mov %ecx, $19  ;; sig = SIGSTOP
int $0x80      ;; after executing this instruction, execution will halt

Then you can mmap ranges from /proc/(pid)/mem to read out the process's memory, or even attach gdb and use its generate-core-file command. Alternately, you could change this to simply raise SIGQUIT or something to trigger a core dump right then and there (assuming wine hasn't installed a SIGQUIT handler - but with the right syscalls that can be overcome as well).

OTHER TIPS

Try doing it like MSVC. They call UnhandledExceptionFilter directly which bypasses application's exception handlers. From gs_report.c (some #ifdefs skipped):

/* Make sure any filter already in place is deleted. */
SetUnhandledExceptionFilter(NULL);
UnhandledExceptionFilter((EXCEPTION_POINTERS *)&GS_ExceptionPointers);
TerminateProcess(GetCurrentProcess(), STATUS_STACK_BUFFER_OVERRUN);

Another possibility is to put an empty handler at the head of the list. Something like this:

#include <stdio.h>
#include <excpt.h>
#include <intrin.h>
int main()
{
  __try
  {
    __writefsdword(0, -1); // put chain end marker (-1) in fs:0
    *(int*)9 = 0;          // trigger the exception
  }
  __except( EXCEPTION_EXECUTE_HANDLER )
  {
    printf("Exception!\n");  // this does not appear
  }
}

Edit: sorry, I didn't notice "don't have the source" until now. But if you can patch the code, you can probably add "mov fs:[0], -1" to it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top