如何修复 C 程序中的 Hook(堆栈的恢复)
How to fix a Hook in a C program (stack's restoration)
这是一种训练任务,因为现在这些方法(我猜)已经行不通了。
使用Win XP和MinGW编译器。不涉及特殊的编译器选项(仅 gcc 声明一个源文件)。
首先保存一个程序退出地址,跳转到某个Hook函数:
// Our system uses 4 bytes for addresses.
typedef unsigned long int DWORD;
// To save an address of the exit from the program.
DWORD addr_ret;
// An entry point.
int main()
{
// To make a direct access to next instructions.
DWORD m[1];
// Saving an address of the exit from the program.
addr_ret = (DWORD) m[4];
// Replacing the exit from the program with a jump to some Hook function.
m[4] = (DWORD) Hook;
// Status code of the program's execution.
return 0;
}
这段代码的目标是获得对系统权限级别的访问权限,因为当我们return(应该return)到系统时,我们只是将我们的程序重定向到我们的一些方法。该方法的代码:
// Label's declaration to make a jump.
jmp_buf label;
void Hook()
{
printf ("Test\n");
// Trying to restore the stack using direct launch (without stack's preparation) of the function (we'll wee it later).
longjmp(label, 1);
// Just to make sure that we won't return here after jump's (from above) finish, because we are not getting stuck in the infinite loop.
while(1) {}
}
最后我将说明一个函数(在我看来)应该修复堆栈指针 - ESP 寄存器:
void FixStack()
{
// A label to make a jump to here.
setjmp(label);
// A replacement of the exit from this function with an exit from the whole program.
DWORD m[1];
m[2] = addr_ret;
}
当然我们应该将这些包含用于所述程序:
#include <stdio.h>
#include <setjmp.h>
该程序的整个逻辑在我的系统中运行正常,但我无法恢复我的堆栈 (ESP),因此该程序 return 是一个不正确的 return 代码。
在上述解决方案之前,我没有使用跳转和FixStack功能。我的意思是这些行在 Hook 函数中而不是跳转和 while 循环:
DWORD m[1];
m[2] = addr_ret;
但是对于这个变体,我在退出程序之前在 ESP 寄存器中得到了一个不正确的值(它比进入这个程序之前这个寄存器的值大 8 个字节)。所以我决定以某种方式添加这 8 个字节(避免 C 程序中的任何 ASM 代码)。这是跳转到 FixStack 函数并从中适当退出的目的(从堆栈中删除一些值)。但是,正如我所说,它不是 return 使用此命令执行程序的正确状态:
echo %ErrorLevel%
所以我的问题非常广泛:从询问调试实用程序的一些使用建议开始(我只使用 OllyDbg),并以描述的 Hook 实现的可能解决方案结束。
好的,我终于可以让我的程序按预期运行了。现在我们可以使用正确的 return 代码启动编译的(我在 Win XP 中使用 MinGW)程序,没有任何错误。
也许对某人有帮助:
#include <stdio.h>
#include <setjmp.h>
typedef unsigned long int DWORD;
DWORD addr_ret;
int FixStack()
{
DWORD m[1];
m[2] = addr_ret;
// This line is very necessary for correct running!
return 0;
}
void Hook()
{
printf("Test\n");
FixStack();
}
int main()
{
DWORD m[1];
addr_ret = (DWORD) m[4];
m[4] = (DWORD) Hook;
}
当然,您似乎已经意识到这只适用于非常特定的构建环境。它绝对不会在 64 位目标上工作(因为地址不是 DWORD-ish)。
您是否有任何理由不想使用 C 标准库提供的工具来执行此操作? (或与此非常相似的内容。)
#include <stdlib.h>
void Hook()
{
printf("Test\n");
}
int main()
{
atexit(Hook);
}
这是一种训练任务,因为现在这些方法(我猜)已经行不通了。
使用Win XP和MinGW编译器。不涉及特殊的编译器选项(仅 gcc 声明一个源文件)。
首先保存一个程序退出地址,跳转到某个Hook函数:
// Our system uses 4 bytes for addresses.
typedef unsigned long int DWORD;
// To save an address of the exit from the program.
DWORD addr_ret;
// An entry point.
int main()
{
// To make a direct access to next instructions.
DWORD m[1];
// Saving an address of the exit from the program.
addr_ret = (DWORD) m[4];
// Replacing the exit from the program with a jump to some Hook function.
m[4] = (DWORD) Hook;
// Status code of the program's execution.
return 0;
}
这段代码的目标是获得对系统权限级别的访问权限,因为当我们return(应该return)到系统时,我们只是将我们的程序重定向到我们的一些方法。该方法的代码:
// Label's declaration to make a jump.
jmp_buf label;
void Hook()
{
printf ("Test\n");
// Trying to restore the stack using direct launch (without stack's preparation) of the function (we'll wee it later).
longjmp(label, 1);
// Just to make sure that we won't return here after jump's (from above) finish, because we are not getting stuck in the infinite loop.
while(1) {}
}
最后我将说明一个函数(在我看来)应该修复堆栈指针 - ESP 寄存器:
void FixStack()
{
// A label to make a jump to here.
setjmp(label);
// A replacement of the exit from this function with an exit from the whole program.
DWORD m[1];
m[2] = addr_ret;
}
当然我们应该将这些包含用于所述程序:
#include <stdio.h>
#include <setjmp.h>
该程序的整个逻辑在我的系统中运行正常,但我无法恢复我的堆栈 (ESP),因此该程序 return 是一个不正确的 return 代码。
在上述解决方案之前,我没有使用跳转和FixStack功能。我的意思是这些行在 Hook 函数中而不是跳转和 while 循环:
DWORD m[1];
m[2] = addr_ret;
但是对于这个变体,我在退出程序之前在 ESP 寄存器中得到了一个不正确的值(它比进入这个程序之前这个寄存器的值大 8 个字节)。所以我决定以某种方式添加这 8 个字节(避免 C 程序中的任何 ASM 代码)。这是跳转到 FixStack 函数并从中适当退出的目的(从堆栈中删除一些值)。但是,正如我所说,它不是 return 使用此命令执行程序的正确状态:
echo %ErrorLevel%
所以我的问题非常广泛:从询问调试实用程序的一些使用建议开始(我只使用 OllyDbg),并以描述的 Hook 实现的可能解决方案结束。
好的,我终于可以让我的程序按预期运行了。现在我们可以使用正确的 return 代码启动编译的(我在 Win XP 中使用 MinGW)程序,没有任何错误。
也许对某人有帮助:
#include <stdio.h>
#include <setjmp.h>
typedef unsigned long int DWORD;
DWORD addr_ret;
int FixStack()
{
DWORD m[1];
m[2] = addr_ret;
// This line is very necessary for correct running!
return 0;
}
void Hook()
{
printf("Test\n");
FixStack();
}
int main()
{
DWORD m[1];
addr_ret = (DWORD) m[4];
m[4] = (DWORD) Hook;
}
当然,您似乎已经意识到这只适用于非常特定的构建环境。它绝对不会在 64 位目标上工作(因为地址不是 DWORD-ish)。
您是否有任何理由不想使用 C 标准库提供的工具来执行此操作? (或与此非常相似的内容。)
#include <stdlib.h>
void Hook()
{
printf("Test\n");
}
int main()
{
atexit(Hook);
}