首页
论坛
课程
招聘
[原创]利用EXE中的数据与代码
2010-5-21 11:02 14572

[原创]利用EXE中的数据与代码

2010-5-21 11:02
14572
某日,逆向一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;
}


[2023春季班]《安卓高级研修班(网课)》月薪两万班招生中~

收藏
点赞0
打赏
分享
最新回复 (27)
雪    币: 4199
活跃值: 活跃值 (1003)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
chinarenjf 活跃值 2010-5-21 12:01
2
0
强大,顶.....
雪    币: 248
活跃值: 活跃值 (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
droiyan 活跃值 2010-5-21 12:49
3
0
换个思路可能更简单,就让HH运行起来,自己要实现啥做到DLL中,注入DLL。EXE里面的函数和代码不就随便给你用了,哈哈。游戏外挂不就经常调用游戏的CALL啥的,很成熟的方案!
雪    币: 329
活跃值: 活跃值 (13)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
ghban 活跃值 2010-5-21 14:16
4
0
不错啊 太强了!! 可能会成为精华贴。
楼上说的是外挂用的方法 但是LZ的更好   LZ的原程序是不运行的!
雪    币: 465
活跃值: 活跃值 (24)
能力值: ( LV12,RANK:250 )
在线值:
发帖
回帖
粉丝
triones 活跃值 6 2010-5-21 15:02
5
0
是的,本文的目的不是实现外挂。主要就是不让原程序运行,而只让副程序运行。
所谓“借尸还魂”或者叫“鬼上身”都比较贴切。嘿嘿。
雪    币: 106
活跃值: 活跃值 (374)
能力值: ( LV13,RANK:970 )
在线值:
发帖
回帖
粉丝
nbw 活跃值 24 2010-5-21 17:47
6
0
我以前写了个小程序,可以获取PE文件内大部分需要重定位的地址,一些SDK程序还是可以跑起来的。
上传的附件:
雪    币: 213
活跃值: 活跃值 (63)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
jasonzhou 活跃值 2010-5-22 14:52
7
0

用LoadLibrary加载CC。
LoadLibrary加载PE文件,找到PE入口,并把入口视作DLLMain,以DLL_PROCESS_ATTACH为参数调用之。
所以不管你是EXE还是DLL,入口总能得到运行。
如此,主线程将被交付CC。


DLL_PROCESS_ATTACH的作用是什么?是不是相当于调试了?
雪    币: 42
活跃值: 活跃值 (32)
能力值: ( LV9,RANK:320 )
在线值:
发帖
回帖
粉丝
charme 活跃值 7 2010-5-22 15:08
8
0
利用exe中的数据和代码

利用jpg文件中的数据和代码

利用txt中的数据和代码

忽忽  楼主做个专题把
雪    币: 237
活跃值: 活跃值 (69)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
YFLK 活跃值 2010-6-13 22:16
9
0
现在也做这方面的研究,但与楼主的研究有些区别,
我的HH是一个独立的可执行EXE,CC也是一个可独立运行的EXE程序,所不同的是,CC可以使用HH的导出函数,现在有个问题,当CC中的导出函数没有使用窗口函数、API和系统资源时可以正常被CC调用使用,否则不能正常运行。
楼主的方法值得借鉴!
雪    币: 237
活跃值: 活跃值 (69)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
YFLK 活跃值 2010-6-13 22:35
10
0
楼主经过你处理,HH和CC还能独立运行吗?
雪    币: 20
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
cblcbl 活跃值 2010-6-14 00:30
11
0
和楼主学习了。都是大牛啊!也不知道什么时候能赶上你们?!
雪    币: 239
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
一叶青 活跃值 2010-6-21 15:10
12
0
虽然看不明白。

继续学习,争取有一天看明白。
雪    币: 202
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
xiongshi 活跃值 2010-6-28 17:15
13
0
特别申明:
其实没有必要那么麻烦,你只要把EXE运行起来,然后用DLL注入到EXE进程,再调用相应的函数就行了,你这个是调用某个函数,如果函数中使用了一些全局对象,就会不正确了.
雪    币: 209
活跃值: 活跃值 (19)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Jeller 活跃值 2010-6-28 21:31
14
0
方法多了去了。。。。
雪    币: 465
活跃值: 活跃值 (24)
能力值: ( LV12,RANK:250 )
在线值:
发帖
回帖
粉丝
triones 活跃值 6 2010-6-28 21:44
15
0
十分荣幸,xiongshi兄弟2007年潜水至今第一帖回复到了这里。。。
让我再次向你解释:原EXE是不运行的。比如:我有一个病毒,只是想利用内部的算法,那不可能让它运行起来让我插DLL吧。。。
而经过处理后的CC也是无法独立运行的,需要由经过处理的HH加载之。除了某些需要初始化的全局对象无法处理。那些静态的全局函数与数据,包含API调用等等,都保持原有状态与位置。使用不会出错。
谢谢
雪    币: 86
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ylts 活跃值 2010-6-28 22:01
16
0
既然是算法 问题  而且还有人说 方法多了去了
真的支持楼主 搞个 专题 交流  虽然 高手不屑一顾
但是可以帮住  新人 吸收知识  积累经验啊
雪    币: 144
活跃值: 活跃值 (44)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
SupRole 活跃值 2010-6-28 23:23
17
0
在CreateProcess里面指定CREATE_SUSPENDED,让他挂着,然后再注入dll不是一样的效果吗
雪    币: 144
活跃值: 活跃值 (44)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
SupRole 活跃值 2010-6-28 23:24
18
0
楼主思路值得学习啊!
雪    币: 84
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
xnop 活跃值 2010-6-30 17:14
19
0
好强大,好思路~~!!!学习啦
雪    币: 327
活跃值: 活跃值 (313)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
renminbi 活跃值 2010-6-30 18:15
20
0
楼主的思路可以利用到很方面的应用,好思路。
雪    币: 86
活跃值: 活跃值 (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
estelle 活跃值 2010-6-30 19:36
21
0
nbw的秘密武器真多啊
雪    币: 48866
活跃值: 活跃值 (171549)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
linhanshi 活跃值 2010-6-30 19:47
22
0
Support.
雪    币: 326
活跃值: 活跃值 (15)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
快雪时晴 活跃值 4 2010-6-30 20:04
23
0
学得一招是一招,讲办法多了去的一般都语焉不详更不愿来个demo/tut
雪    币: 488
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
hankcs 活跃值 2010-6-30 20:21
24
0
netline.h是什么文件?
雪    币: 218
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
htsf110 活跃值 2010-7-3 16:00
25
0
新的思路,支持一下
游客
登录 | 注册 方可回帖
返回