这是一种训练任务,因为现在这些方法(我猜)不再适用了。
使用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;
}
此代码的目标是获取对系统特权级别的访问权限,因为当我们返回(应该返回)系统时,我们只是将程序重定向到我们的一些方法。这种方法的代码:
// 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),因此程序返回错误的返回码。
在上述解决方案之前,我没有使用跳转和FixStack功能。我的意思是这些线在Hook函数中而不是跳跃和循环:
DWORD m[1];
m[2] = addr_ret;
但是对于这个变体,我在退出程序之前在ESP寄存器中得到了一个不正确的值(它比在该程序中输入之前的寄存器值大8个字节)。所以我决定以某种方式添加这8个字节(避免在C程序中的任何ASM代码)。它的目的是跳转到FixStack函数并从中适当退出(从堆栈中删除一些值)。但是,正如我所说,它不会使用此命令返回程序执行的正确状态:
echo %ErrorLevel%
所以我的问题非常广泛:从使用调试实用程序(我只使用OllyDbg)中提出一些建议开始,并结束所描述的Hook实现的可能解决方案。
答案 0 :(得分:0)
好的,我最终可以按照预期的方式使我的程序正常工作。现在我们可以启动编译(我在Win XP中使用MinGW)程序,没有任何错误和正确的返回代码。
也许对某人有帮助:
foreign key (rm_id) references roomate.rm_id,
答案 1 :(得分:0)
当然,您似乎已经意识到这只适用于非常具体的构建环境。它绝对不会在64位目标上工作(因为地址不是DWORD-ish)。
您是否有任何理由不想使用C标准库提供的功能来完成此操作? (或者与此非常相似的东西。)
#include <stdlib.h>
void Hook()
{
printf("Test\n");
}
int main()
{
atexit(Hook);
}