[已经解决]向执行文件exe写入shellcode的疑问(E8计算)
本帖最后由 richard_ljd 于 2024-9-17 08:25 编辑问题解决了
我命名的变量名codebegin把自己迷惑住了,那个只是在FIlebuffer文件状态下的地址,要写入内存状态的地址才行,
因为我自己命名时codebegin,我以为已经算的是Imagebuffer的地址,结果少了一个Imagebase,所以一直有错,函数改了一下就好了
//复制CALL,且计算 MESSAGEBOX_WZ - (CALL + 5)实际参数,计算下一句地址需要 - PointerToRawData + VirtualAddress得到内存状态实际地址
int call_s = MESSAGEBOXW_WZ - (pOptionHeader->ImageBase + codebegin + 0xD); //<------------这里
BYTE c_wz;
mitol(call_s, c_wz);
memcpy(Shellcode + 0x9, c_wz, 4);
==================================================================================
最近在看教程,老师让用代码的方式自动在程序中写入ShellCode,且能够运行
在手动写入了以后,我也开始了代码写入,先简单来说一下过程
首先程序读入exe文件到FileBuffer,然后进行PE分析,分析完毕以后将FileBuffer转变成ImageBuffer,
随后我将我的ShellCode在这个ImageBuffer中寻找有空闲区域的节(防止自己写入的代码被覆盖),找到以后VirtualAddress + VirtualSize可以到节尾,
BYTE Shellcode[] =
{
0x6A,00,0x6A,00,0x6A,00,0x6A,00,
0xE8,00,00,00,00,
0xE9,00,00,00,00
};
int PeHeader::AddShellcode(int Number)
{
int fsize = 0;
//遍历节,看是否有可以写入的节区
for (Number - 1; Number < pPEHeader->NumberOfSections; Number++)
{
fsize = (pSectionHeader + Number)->SizeOfRawData - (pSectionHeader + Number)->Misc.VirtualSize;
if (fsize > Shellcode_length)
break;
if (Number == pPEHeader->NumberOfSections - 1)
return 0;
}
int codebegin = (pSectionHeader + Number)->VirtualAddress + (pSectionHeader + Number)->Misc.VirtualSize;
//复制CALL,且计算 MESSAGEBOX_WZ - (CALL + 5)实际参数,计算下一句地址需要 - PointerToRawData + VirtualAddress得到内存状态实际地址
int call_s = MESSAGEBOXW_WZ - (codebegin + 0xE);
BYTE c_wz;
mitol(call_s, c_wz);
memcpy(Shellcode + 0x9, c_wz, 4);
//复制JMP,且计算 OEP - (JMP + 5)实际参数
int jmp_s = pOptionHeader->AddressOfEntryPoint - (codebegin + 18);
BYTE j_wz;
mitol(jmp_s, j_wz);
memcpy(Shellcode + 0xE, j_wz, 4);
//修改OEP,指向添加代码的位置
BYTE OEP;
mitol((pSectionHeader + Number)->Misc.VirtualSize + (pSectionHeader + Number)->VirtualAddress, OEP);
memcpy((void*)((DWORD)pNewBuffer + ((DWORD)pOptionHeader - (DWORD)pDosHeader) + 0x10), OEP, 4);
//将计算好的ShellCode写入pNewBuffer
memcpy((void*)((DWORD)pNewBuffer + codebegin), Shellcode, 18);
return pOptionHeader->AddressOfEntryPoint;
}
然后如上面这个代码段,添加CALL和JMP的地址,修改OEP
代码方面计算基本没有问题(实际有问题,也是这个帖子发出来的原因,不过先继续)
程序跑起来以后,直接运行引发未知错误直接结束,所以我挂上dbg
这个报错提示告诉我:1.指针为空2.数组越界 3.堆栈溢出 4.内存损坏 5.硬件问题 6.无权限
这六个可能中前5个不好评价,第六个的话也不清楚怎么办(但是应该好歹调试器里面会显示到正确的位置吧)
于是我打算进程序里面看看,跟着jmp走了一会跳进了程序
这边用的是FF15,我尝试改成E8
发现也是可以的,但是回到我的Shellcode就直接炸了,不清楚为什么
下面是完整的代码,能Filebuffer和Imagebuffer相互转换,然后就没什么了()
微云网盘:https://share.weiyun.com/lVcTTb6Q
百度网盘:https://pan.baidu.com/s/1Y4XIVcBEDwEpQE2O9SES_A 提取码:1234
Vvvvvoid 发表于 2024-9-16 15:32
shell code 写成这样试试
pushad
push 0
你说的是这种么?裸函数,然后内联汇编,随后直接复制出来就是完整代码
int __declspec(naked) shellcode()
{
_asm {
push 0;
push 0;
push 0;
push 0;
CALL MessageBoxA;
}
}
int (*p)() = shellcode;
这个虽然是一种办法,但是麻烦的还是E8跳转时Messagebox经过计算的位置才行,如果放在代码内部,这个计算是根据这个函数位置进行计算,我写到其他地方也失效了
如果我理解错了希望能够指出来 richard_ljd 发表于 2024-9-17 08:03
是很早,早到没法查(),所以这个阶段我想去调用函数都是用dbg进去先查好的用,就像代码里的宏MESSAGEBO ...
仔细看了下 你的代码, 出错的地方 在这里 int call_s = MESSAGEBOXW_WZ - (codebegin + 0xE);
//运行出错 是因为 实际运行 call_s-= (模块起始地址 +1);
BYTE c_wz;
mitol(call_s, c_wz); 你给这个变量加个重定位 让他在运行的时候自己修正。试试
shell code 写成这样试试
pushad
push 0
push 0
push 0
push 0
call MessageBoxA
popad
ret richard_ljd 发表于 2024-9-16 15:43
你说的是这种么?裸函数,然后内联汇编,随后直接复制出来就是完整代码
int __declspec(naked) shellc ...
楼上的意思是shellcode增加pushad、popad,保存寄存器环境,避免返回到原来汇编处污染寄存器数据 woflant 发表于 2024-9-16 16:45
楼上的意思是shellcode增加pushad、popad,保存寄存器环境,避免返回到原来汇编处污染寄存器数据
az,这个东西是把原本oep换成自己的代码,代码跑完就转到原本的oep,不会再回来了,如果硬要说的话得
pushad
push 0
push 0
push 0
push 0
call messagebox
popad
jmp 原oep
代码不会运行回来
messagebox我没记错的话影响的返回值在eax,不会造成什么太大影响,未来写更多东西的时候我注意一下 如果 你在OEP之前运行 会不会 时机太早 ,要自己获取下MessageBoxA 的地址 才行。 这样确实有隐患问题,想如果是APIHOOK,微软有热补丁前五个字节用来修改,你要是在OEP前执行代码,原本的寄存器的值,还有栈帧被修改,跳转到OEP的时候没有被还原,是这个问题吗? 海水很咸 发表于 2024-9-16 19:12
如果 你在OEP之前运行 会不会 时机太早 ,要自己获取下MessageBoxA 的地址 才行。
是很早,早到没法查(),所以这个阶段我想去调用函数都是用dbg进去先查好的用,就像代码里的宏MESSAGEBOX_WZ就是MesssageboxW函数的地址,不过计算是一方面,我自己进到我写入ShellCode的程序,手算填进去也无法找到,这就是我问题的来源() 海水很咸 发表于 2024-9-18 18:22
仔细看了下 你的代码, 出错的地方 在这里 int call_s = MESSAGEBOXW_WZ - (co ...
这点我当时调试的时候发现了,已经改正,不过主要问题不是在于这里,问题在于codebegin这个变量本来应该实在Imagebuffer中的地址,但是我没有加入Imagebase,所以一下子地址差了40000,所以出现报错(都跑程序外了,这还不报错),加上以后就好了,你可以看一下我修改了最开始的帖子。
页:
[1]
2