views:

17

answers:

2

Hi, 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.

+3  A: 

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).

bdonlan
Interesting... I could do that. However I've never compiled `wine` before - and it would probably take a long time to find all the right places. I hope that someone else can come up with something easier (... said the man trying to rev-eng a protected app under a half-correct emulator ..., yeah I see the irony)
viraptor
Added an alternate approach
bdonlan
Unfortunately wine seems to take care of SIGSTOP, because I just see more SEH messages in the logs.
viraptor
SIGSTOP cannot be caught. I'd check that that code is really working properly, though - I didn't test it :) Try putting it into a standalone linux program and seeing if it works properly...
bdonlan
A: 

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.

Igor Skochinsky