某日,逆向一EXE(这里命名它为HH),发现内部使用了Rijndael-256,以及某个不知名的算法。
从网上找到N个相关AES算法的实现,结果密码表是一样了,但运行结果却怎么都不一样。
由于实在对AES头晕,再加上还有某个不知名的算法(内部流程复杂),所以考虑需要利用这个EXE的加解密实现。
可是EXE不是DLL,没有重定位表。不能像DLL一样Load一下,直接CALL就能用。
怎么办?把EXE当DLL使?修正重定位信息?网上找了找,基本是这个说法,但说法的后面,也明确指出:依然不足,修正重定位信息是件苦力活,还容易出错。
而且,N个地方需要重定位,这一路做下来,不吐血也脑溢血了。
考虑考虑怎么取巧吧。
思路:
首先,自己写的利用程序(这里命名它为CC)是可以设置有重定位信息的,所以可以让出EXE的默认加载位置。
把HH放在400000位置,嘿嘿,重定位不就省了?
。。。
说得容易,实现一下看看?指定CC加载到别处,设置重定位,MapViewOfFileEx把HH加载到0x400000。
报错?不行?不行!
什么错?目标位置已被使用,无法加载?!
OD看看,果然,让出来的茅坑让系统给用了。
再想:
由于茅坑让出来了,系统就认为是无主的,爱怎么用,用多少,咱管不到。
就算这个茅坑系统没有使用,万一HH屁股比较大,需要连坐N个坑,那就保不齐系统把后面坑占走,害HH屁股装不下了。。。
如何通知系统留着坑哩?
试着手工打造一个占坑PE。试来试去,不尽人意。
又想:
最好的办法是让HH自己占。
可是HH自己占坑就得运行,我们只想使用数据与代码,不想它运行起来。
于是需要改造HH入口。
由于HH入口承接着主线程,不能让它结束。正好,把主线程转移给CC。
用LoadLibrary加载CC。
LoadLibrary加载PE文件,找到PE入口,并把入口视作DLLMain,以DLL_PROCESS_ATTACH为参数调用之。
所以不管你是EXE还是DLL,入口总能得到运行。
如此,主线程将被交付CC。
试试呗。
实现CC,内部使用HH的绝对地址。当然,这样CC程序是不能独立运行的。
修改HH入口,指定加载CC。
不成功?CC无法加载。
其实是小问题,用LordPE把CC的Characteristics加上DLL标志。
再来,成功了!!!成功利用了HH内部数据与代码!!!
好,再分析一下细节:注意到可能CC与HH的子系统不同,所以需要统一子系统。
另外,如果HH加过壳,这个方法就不能直接使用了。虽然俺不大会脱,但总有牛人会脱,脱了壳再应用,一样一样的。
给出实现DEMO:
// Replacer.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <windows.h>
#include <iostream>
using namespace std;
#include "netline.h"
void usage()
{
cout<<endl;
cout<<"Usage: Replacer Host Client [Client_argv]\n"<<endl;
cout<<"Options:"<<endl;
cout<<" Host\t将占用原有的原始空间"<<endl;
cout<<" Client\t将作为DLL被加载,需要有重定位信息"<<endl;
cout<<"\t\t主线程将被交付到入口"<<endl;
cout<<"\t\t注意导入库可能无法正确识别(环境设置)"<<endl;
cout<<" Client_argv\t将被用于Client启动参数\n"<<endl;
}
unsigned long GetRAbyRVA(HANDLE hMapView,unsigned long RVA)
{
IMAGE_DOS_HEADER* doshead = (IMAGE_DOS_HEADER*)hMapView;
IMAGE_NT_HEADERS* PEhead = (IMAGE_NT_HEADERS*)((unsigned long)doshead + (unsigned long)doshead->e_lfanew);
IMAGE_SECTION_HEADER* ISH = (IMAGE_SECTION_HEADER*)((unsigned long)PEhead + sizeof(IMAGE_NT_HEADERS));
IMAGE_EXPORT_DIRECTORY* lpExpF = 0;
for(int i=0;i<PEhead->FileHeader.NumberOfSections;++i)
{
if(RVA>=ISH->VirtualAddress && RVA<=(ISH->VirtualAddress+ISH->Misc.VirtualSize))
{
return( (unsigned long)hMapView + ISH->PointerToRawData + RVA - ISH->VirtualAddress );
}
++ISH;
}
return 0;
}
const TCHAR* hostEXE = TEXT("host.exe");
const TCHAR* clientEXE = TEXT("client.exe");
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hMapView = 0;
try
{
if(argc<3) throw runtime_error("");
cout<<"配置Client中...";
if(!CopyFile(argv[2],clientEXE,false)) throw runtime_error("复制Client文件失败!");
HANDLE hFile = CreateFile(clientEXE,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
if(hFile == INVALID_HANDLE_VALUE) throw runtime_error("打开Client文件失败!");
HANDLE hFileMapping = CreateFileMapping(hFile,0,PAGE_READWRITE,0,0,0);
CloseHandle(hFile);
if(!hFileMapping) throw runtime_error("CreateFileMapping失败!");
hMapView = MapViewOfFile(hFileMapping,FILE_MAP_READ|FILE_MAP_WRITE,0,0,0);
CloseHandle(hFileMapping);
if(!hMapView) throw runtime_error("MapViewOfFile失败!");
IMAGE_DOS_HEADER* doshead = (IMAGE_DOS_HEADER*)hMapView;
if(doshead->e_magic != 'ZM') throw runtime_error("检测MZ标志失败!");
IMAGE_NT_HEADERS* PEhead = (IMAGE_NT_HEADERS*)((unsigned long)doshead + (unsigned long)doshead->e_lfanew);
if(PEhead->Signature != 'EP') throw runtime_error("检测PE标志失败!");
WORD subsystem = PEhead->OptionalHeader.Subsystem; //得到子系统
IMAGE_DATA_DIRECTORY* IDD = PEhead->OptionalHeader.DataDirectory;
IDD+=5; //指向重定位表
if(IDD->Size==0) throw runtime_error("Client没有重定位表,无法继续!");
if((IMAGE_FILE_DLL & PEhead->FileHeader.Characteristics)!=IMAGE_FILE_DLL)
{
cout<<"Client没有DLL标志,加载修改成DLL...";
PEhead->FileHeader.Characteristics = PEhead->FileHeader.Characteristics | IMAGE_FILE_DLL;
}
UnmapViewOfFile(hMapView);
hMapView = 0;
cout<<"完成!"<<endl;
cout<<"配置Host中...";
if(!CopyFile(argv[1],hostEXE,false)) throw runtime_error("复制Host文件失败!");
hFile = CreateFile(hostEXE,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
if(hFile == INVALID_HANDLE_VALUE) throw runtime_error("打开Host文件失败!");
hFileMapping = CreateFileMapping(hFile,0,PAGE_READWRITE,0,0,0);
CloseHandle(hFile);
if(!hFileMapping) throw runtime_error("CreateFileMapping失败!");
hMapView = MapViewOfFile(hFileMapping,FILE_MAP_READ|FILE_MAP_WRITE,0,0,0);
CloseHandle(hFileMapping);
if(!hMapView) throw runtime_error("MapViewOfFile失败!");
doshead = (IMAGE_DOS_HEADER*)hMapView;
if(doshead->e_magic != 'ZM') throw runtime_error("检测MZ标志失败!");
PEhead = (IMAGE_NT_HEADERS*)((unsigned long)doshead + (unsigned long)doshead->e_lfanew);
if(PEhead->Signature != 'EP') throw runtime_error("检测PE标志失败!");
if(subsystem!=PEhead->OptionalHeader.Subsystem)
{
cout<<"Host与Client的子系统不同,修改匹配之...";
PEhead->OptionalHeader.Subsystem = subsystem;
}
cout<<"\n重做Host入口...";
unsigned long Entry = PEhead->OptionalHeader.AddressOfEntryPoint;
Entry = GetRAbyRVA(hMapView,Entry);
int ClientName_len = _tcslen(clientEXE)+sizeof(TCHAR);
ClientName_len*=2;
HMODULE hMod = GetModuleHandle(TEXT("Kernel32.dll"));
unsigned long LodLib = (unsigned long)GetProcAddress(hMod,"LoadLibraryW");
netline nline;
nline.net(false);
nline<<(unsigned char)0xB8<<LodLib; //mov eax, LoadLibrary
nline<<(unsigned char)0xE8; //call ...
nline<<ClientName_len;
nline.setstr((unsigned char*)clientEXE,ClientName_len);
nline.setstr((unsigned char*)"\xFF\xD0\xC2\x10\x00",5); //call eax retn 10
nline.getstr((unsigned char*)Entry,(int)nline);
cout<<"搞定!"<<endl;
UnmapViewOfFile(hMapView);
hMapView = 0;
}
catch (runtime_error &err)
{
DeleteFile(clientEXE);
DeleteFile(hostEXE);
if(hMapView)UnmapViewOfFile(hMapView);
cout<<err.what()<<endl;
usage();
}
catch (...)
{
cout<<"未知异常!"<<endl;
usage();
}
return 0;
}
[培训]《安卓高级研修班(网课)》月薪三万计划