Форсирование coredump через Wine, игнорируя SEH - PullRequest
1 голос
/ 29 августа 2010

Я бы хотел вызвать coredump из программы (или посмотреть ее память в другое время другим способом).Однако есть несколько проблем:

  • Я запускаю его под Wine (не могу запустить через winedbg, потому что приложение его обнаруживает)
  • Приложение использует исключения / SEH / другиеобработчики, которые записывают нестандартные события
  • Даже присоединение strace останавливает работу программы
  • Я бы хотел поэкспериментировать, поэтому нет конкретных областей, которые я мог бы напечатать
  • Ну ... у меня нет источника

Я пытался изменить код на оба:

xor eax, eax
call eax

и некоторые случайные вещи, которые не былиреальная инструкция - оба раза SEH включил и спас приложение.

Как я могу получить информацию?Мне нужно изображение из памяти определенного времени и я могу исправить место, где оно происходит.

Ответы [ 2 ]

3 голосов
/ 29 августа 2010

Поскольку у вас есть доступ к исходному коду wine, я бы предложил просто изменить код wine SEH и / или реализовать функцию IsDebuggerPresent().

Еще один вариант - изменить приложение так, чтобы оно приостанавливалось, вызывая сигнал SIGSTOP. Приложения для Windows в Wine по-прежнему могут получать доступ к API-интерфейсам Linux, вызывая int $0x80, так что вы можете добавить некоторый код, подобный следующему:

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

Затем вы можете mmap в диапазоне от /proc/(pid)/mem, чтобы считывать память процесса, или даже присоединить gdb и использовать команду generate-core-file. С другой стороны, вы можете изменить это, чтобы просто поднять SIGQUIT или что-то еще, чтобы тут же вызвать дамп ядра (при условии, что у Wine не установлен обработчик SIGQUIT - но с правильными системными вызовами, которые также можно преодолеть). 1014 *

0 голосов
/ 30 августа 2010

Попробуйте сделать это как MSVC. Они вызывают UnhandledExceptionFilter напрямую, что обходит обработчики исключений приложения. Из gs_report.c (пропущены некоторые #ifdefs):

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

Другая возможность - поместить пустой обработчик в начало списка. Примерно так:

#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
  }
}

Редактировать: извините, я не заметил "не имею источника" до сих пор. Но если вы можете исправить код, вы, вероятно, можете добавить к нему «mov fs: [0], -1».

...