我试图通过更改它的EIP来破解另一个程序。有两个程序正在运行,一个是目标,它告诉作为“核心功能”的功能(例如,接收密码字符串作为参数并返回true或false的函数)在内存中。 然后现在我知道核心功能在哪里我想用其他程序修改EIP,这样目标程序就可以调用我的函数,只需从中获取一个真实的信息并打印出一个漂亮的“访问权限”。
我的代码现在是这样的:
目标计划:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int checkPwd(char *pwd)
{
printf("\nstill in the function\n");
if(strcmp(pwd, "patrick") == 0) return true;
else return false;
}
int main()
{
char pwd[16];
printf("%d", checkPwd);
scanf("%s", &pwd);
system("pause");
if(checkPwd(pwd)) printf("Granted!\n");
else printf("Not granted\n");
system("pause");
}
攻击者计划:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
int returnTrue()
{
return true;
}
int main()
{
int hex;
scanf("%d", &hex);
memcpy((void*)hex, (void*)returnTrue, sizeof(char)*8);
system("pause");
}
我想补充一点,我试图直接将十六进制代码(没有scanf部分)放入攻击者程序中并且不起作用,它崩溃了。
所以我觉得我在这里错过了理论的某些部分。我很高兴知道它是什么。
提前致谢。
答案 0 :(得分:5)
这不起作用 - 进程占用不同的内存空间!
现代操作系统旨在保护用户程序免受此类攻击。一个进程无法访问另一个进程的内存 - 实际上,数据地址仅在该进程内有效。
程序运行时,它有自己的内存视图,只能“看到”内核已指示memory management unit (MMU)映射的内存。
一些参考文献:
答案 1 :(得分:2)
可以将一个函数注入另一个进程,但它比你想象的要多一些。首先,你需要通过创建两个函数来实现这个功能的适当长度。
static int realFunction() { ... }
static void realFunctionEnd() {}
现在当您复制该功能时,请执行以下操作:
realFunctionEnd - realFunction
这会给你大小。现在你不能只调用其他函数,因为如上所述,他们不保证在其他进程中处于相同的地址,但是你可以假设,我会假设windows,kernal32.dll在同一个地址,所以你实际上可以在创建远程线程时将其传递给realFunction。
现在,关于你的真正问题。您需要做的是注入一个DLL或将一个函数复制到另一个进程,然后挂钩您需要更改的函数。您可以通过复制另一个函数并使该代码可执行,然后通过跳转到您注入的代码覆盖目标函数的前五个字节来完成此操作,或者您可以执行适当的绕行类型挂钩。无论哪种情况都应该有效。或者,您可以在函数中找到偏移量并通过编写适当的操作码代替实际代码来自行修补,例如返回true。
完成此操作需要进行某种注射或修补,您有基本的想法,但目前还有一些比您想象的更多。我有工作代码用于将一个函数复制到另一个进程,但我相信这是一个很好的学习经验。