我在第二次记忆时遇到错误 memcpy(& check_user,& ZZZ,(int)& main - (int)& check_user);
11.exe中的0x72cc1f57(msvcr100.dll)处的未处理异常:0xC0000005:访问冲突写入位置0x00f31000。“
有什么问题?
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <stdio.h>
#include <iostream>
#define PASSWD "+++"
#define MAX_LEN 1023
#define MAX_CODE_SIZE (0x10 * 1024)
#define OFFSET_1 0x42
#define OFFSET_2 0x67
#define x_original_1 0xc01b0574
#define x_original_2 0x44681574
#define x_original_all 0x13D4C04B
#define x_crypt 0x66
using namespace std;
int check_user()
{
char passwd[MAX_LEN];
cout<< "enter password:";
fgets(passwd, MAX_LEN, stdin);
return ~strcmp(passwd, PASSWD);
}
int my_func()
{
if (check_user())
{
cout<<"passwd ok\n";
}
else
{
cout<<"wrong passwd\n";
exit(-1);
}
return 0;
}
int main()
{
int a, b = 0;
#pragma pack(1)
union f
{
char buf[MAX_CODE_SIZE];
struct
{
int local_var_1;
int local_var_2;
char gag_1[OFFSET_1 - sizeof(int) * 2];
int x_val_1;
char gag_2[OFFSET_2 - OFFSET_1 - sizeof(int)];
int x_val_2;
};
};
union f ZZZ;
memcpy(&ZZZ, &check_user, (int)&main - (int)&check_user);
for (a = 0; a < (int)&main - (int)&check_user; a++)
{
(*(char *) ((int)&ZZZ + a)) ^= x_crypt;
}
memcpy(&check_user, &ZZZ, (int)&main - (int)&check_user);
for (a = 0; a < (int)&main - (int)&check_user; a++)
{
b += *(int *)((int)&check_user + a);
}
if (b != x_original_all)
{
fprintf(stderr, "-ERR: invalid CRC (%x)\n", b);
return 0;
}
my_func();
}
答案 0 :(得分:1)
行。这很奇怪,但我想我明白了。您希望通过XOR对某些代码进行“加密”。
您将不得不在自己分配的内存缓冲区中执行此操作,该缓冲区是可读写的,也是可执行的。在Windows上,您可以使用VirtualAlloc()
实现此目的。在Unix上,您可以将mmap()
与MAP_ANON
一起使用。请参阅其中任何一个调用的保护标志:再次需要可写的可执行内存。
此外,通过函数指针直接与此进行交互是一种粗略的方式。我认为你应该编写一些代码,编译/汇编它们,应用某种类型的密码,并将你的混淆代码作为一个字节序列放入。或类似的东西。
我提到这是一个坏主意吗?
答案 1 :(得分:0)
您正在尝试写入函数check_user
的内存位置。
此函数的代码必须位于只读存储器位置,不允许您写入。
答案 2 :(得分:0)
您正在尝试写入&amp; check_user,这是一个函数。
程序的代码段很可能是受保护/只读的。
在旧机器上,写入代码段是可能的,但很危险。 现代机器/操作系统根本不允许这样做。
答案 3 :(得分:0)
使用此“技术”
无法获得功能的“大小”答案 4 :(得分:0)
正如ssg所写,你不能指望复制代码内存完全可以工作。此外,(int)&main - (int)&check_user
可能是负值,因为main
不能保证位于内存中check_user
之上。
答案 5 :(得分:0)
如果您尝试创建自修改代码,则需要将此代码放在数据部分中,并通知Windows该区域不应受DEP保护(它将位于支持NX位的处理器上)
可在此处找到更多信息:Windows ISV Security.请注意,在所有情况下都需要通过指针调用函数。如果您的代码最初没有修改,则可以在启动时初始化指向代码部分的指针。