Функция WinAPI IsDebuggerPresent определяет запущена ли программа под отладчиком или нет. Если под отладчиком, из функции возвращается "не ноль", если не под отладчиком - ноль.
В условном языке высокого уровня это например означает что после вызова:
r = IsDebuggerPresent()
в переменной r будет 0, если программа запущена не под отладчиком, и что-то другое, если нет.
В машинном коде все по-другому. Здесь применяются низкоуровневые правила обмена данными, в том числе между кодом и вызываемыми функциями (Application binary interface, ABI). В разных операционных системах эти правила различаются.
Для 32-битного кода под Windows при обращении к функция WinAPI применяются соглашения stdcall и cdecl (см. Соглашения о вызове в Википедии). Если вкратце, то параметры в функции передаются через стек (push перед вызовом функции через call), возвращаемое значение возвращается через регистр eax. stdcall и cdecl различаются только тем, кто выравнивает указатель стека на размер переданных в функцию параметров после окончания работы функции - сама функция или вызывающий код. В данном случае это не существенно, т.к. у функции IsDebuggerPresent вообще нет параметров.
Теперь смотрим снова на ваш код. После вызова функции IsDebuggerPresent проверяется значение в регистре eax. Для этого выполняется команда test eax, eax. По сути это побитовое сравнение числа самого с собой. На первый взгляд это не имеет смысла, но на самом деле, если в eax лежал ноль, то после операции test в регистре флагов устанавливается (становится 1) бит ZF, который как бы говорит, что результат последней операции был нулём. См. вопрос Явные отличия CMP от TEST
. См. также Регистр флагов в Википедии.
Дальше идет команда jz short loc_401884. Это команда условного перехода, т.е. переход по определенному адресу, если выполняется какое-то условие. В данном случае переход по адресу метки loc_401884 происходит, если в регистре флагов установлен бит ZF.
Таким образом, если программа запущена не под отладчиком, то в процессе исполнения кода произойдет переход по метке loc_401884. Если под отладчиком, переход не произойдет, дальше выполнится команда jmp short loc_401889, произойдет переход по метке loc_401889.
Как избавиться от проверки? Несколько вариантов:
- Убрать вызов функции
IsDebuggerPresent, вместо него записать в регистр eax 0. Или заменить на вызов какой-то функции, которая гарантированно вернет 0 (хотя это уже излишнее усложнение).
- Заменить
test eax, eax на операцию, результатом которой будет ноль. Например xor eax, eax (результат всегда будет 0, в регистр eax запишется 0).
- Заменить условный переход
jz short loc_401884 на безусловный jmp short loc_401884, чтобы вне зависимости от результата вызова функции IsDebuggerPresent всегда происходил переход на ветку кода, которая обрабатывает вариант, когда программа запущена не под отладчиком.