首页
社区
课程
招聘
[原创]IDB2EXE.idc 一个从IDB文件生成EXE文件的idc脚本示例
发表于: 2010-1-6 16:15 21406

[原创]IDB2EXE.idc 一个从IDB文件生成EXE文件的idc脚本示例

2010-1-6 16:15
21406
#include <idc.idc>

//
//+++++++++++++++++++++++++++++++++++++++++++++
//
// IDB2EXE.idc 
//
// Written by Spark.   nkspark_at_gmail.com
// 
//          2010.01.06
//+++++++++++++++++++++++++++++++++++++++++++++
//

#define E_MAGIC 							0x5a4d
#define E_LFANEW							0xe0
#define E_LFANEW_OFFSET				0x3c
#define SIGNATURE 						0x00004550
#define MACHINE								0x014c
#define SECTIONNUMBER_OFFSET	0x06
#define IAT_OFFSET						0x80
#define PEHEADERLENGTH				0xf8
#define SECTIONTABLE_OFFSET		E_LFANEW + PEHEADERLENGTH
#define SECTIONENTRYLENGTH		0x28


static GetIDBFilePath()
{
	auto strIDBFilePath;//idb full path name;
	auto strEXEFileName;
	auto iNameEnd;
	auto iPathEnd;
	auto strPath;
	auto pFile;
	
	strPath = GetInputFilePath();
	strEXEFileName = GetInputFile();
	iPathEnd = strstr(strPath,strEXEFileName);
	iNameEnd = strstr(strEXEFileName,".");
	strIDBFilePath = substr(strPath,0,iPathEnd) + substr(strEXEFileName,0,iNameEnd) + ".idb";
	
	//Message("idb file lies in %s\n",strIDBFilePath);
	
	pFile = fopen(strIDBFilePath,"r");
	if(!pFile)
	{
		strIDBFilePath = AskStr(strIDBFilePath,"Please provide the path of IDB file:");
		return strIDBFilePath;
	}
	fclose(pFile);
	return 	strIDBFilePath;
}

//从IDB文件中获取IAT的偏移地址
static GetIATOffset(strIDBFilePath, PEHeaderOffset)
{
		auto pIDB;
		auto IATOffset;
		
		pIDB =fopen(strIDBFilePath,"rb");

		if(!pIDB)
		{
			Message("Can not open idb file!\n");
			return -1;
		}
		
		fseek(pIDB,PEHeaderOffset + IAT_OFFSET,0);
		IATOffset = readlong(pIDB,0);

		fclose(pIDB);
		return IATOffset;
	
}

//从IDB文件中获取PE头的起始地址
static SearchPEHeader(pIDB)
{
		auto PEHeaderOffset;
		auto i;
		auto iFileSize;
		
		
		fseek(pIDB,0x0,2);
		iFileSize = ftell(pIDB);
		
		if( iFileSize == -1)
			return -1;
		
		for(i=0;i<iFileSize;i++)
		{
			fseek(pIDB,i,0);
			//Signature "PE"
			if(readlong(pIDB,0) == SIGNATURE)
				//Machine 0x014c
				if(readshort(pIDB,0) == MACHINE)
				{
					PEHeaderOffset=ftell(pIDB);
					PEHeaderOffset = PEHeaderOffset -0x06;
					return PEHeaderOffset;					
				}
		}		
		return -1;
}

//IDB中的FirstThrunk已经被IDA自动填充,需要清理回原状
static PatchIAT(addrImageBase, addrIAT)
{		
		auto addrOriginalFirstThunk;
		auto addrFirstThunk;
		auto ValueOfIAT;
		
		Message("Start patching IAT at %x\n",addrIAT);
		
		if(Dword(addrIAT) == BADADDR)
		{
			Message("IAT data was not loaded into IDB file!\n");
			return -1;
		}
		
		do
		{
			addrOriginalFirstThunk = addrImageBase + Dword(addrIAT);
			addrFirstThunk = addrImageBase + Dword(addrIAT+0x10);
			
			do
			{
				PatchDword(addrFirstThunk,Dword(addrOriginalFirstThunk));
				addrOriginalFirstThunk = addrOriginalFirstThunk +0x04;
				addrFirstThunk = addrFirstThunk +0x04;
									
			}while(Dword(addrOriginalFirstThunk) != 0);
			
			addrIAT = addrIAT + 0x14;
			
		}while(Dword(addrIAT) != 0);
		
}

//为创建的EXE文件生成一个PE头
static BuildHeader(pFile,strIDBFilePath)
{
		auto i,j;
		auto pIDB;
		auto addrPE;
		auto iSectionNumber;
		auto lByte;

		pIDB =fopen(strIDBFilePath,"rb");
		if(!pIDB)
		{
			Message("Can not open idb file!\n");
			return -1;
		}
		
		fseek(pFile,0x0,0);
		writeshort(pFile,E_MAGIC,0);
		fseek(pFile,E_LFANEW_OFFSET,0);
		writeshort(pFile,E_LFANEW,0);
		
		
		addrPE = SearchPEHeader(pIDB);
		if(addrPE == -1)
		{
			Message("Can not find PE header in IDB file!\n");
			return -1;
		}
		Message("PEHeaderOffset is %x\n",addrPE);
		
		fseek(pIDB,addrPE,0);
		fseek(pFile,E_LFANEW,0);
		
		//Copy PE header
		//IAT should be set to 0 later!!!
		for(i=0;i<PEHEADERLENGTH;i++)
		{
				lByte = fgetc(pIDB);
				fputc(lByte,pFile);
		}

		fseek(pIDB,addrPE+SECTIONNUMBER_OFFSET,0);
		
		iSectionNumber = fgetc(pIDB);
					
		Message("there are %d sections!\n",iSectionNumber);
		
		//Prepare to write section table
		fseek(pFile,SECTIONTABLE_OFFSET,0);
		fseek(pIDB,addrPE+SECTIONTABLE_OFFSET-E_LFANEW,0);
		
		for(j=0;j<iSectionNumber;j++)
		{
			
			//每个表项有6字节偏移;
			fseek(pIDB,6,1);
			//最后一个表项有多余4字节偏移;
			if(j == (iSectionNumber-1))
				fseek(pIDB,4,1);
			
			
			//section table should be corrected later!!!!		
			for(i=0;i<SECTIONENTRYLENGTH;i++)
			{
					lByte = fgetc(pIDB);
					fputc(lByte,pFile);
			}
			Message("write %d section table!\n",j);
		}
		fclose(pIDB);
		
		//返回addrPE以备后用 :)
		return addrPE;
		
}

//内存地址转换为文件地址
static RVA2FA(pFile)
{
		auto iSectionNumber;
		auto iSectionBase;
		auto i;
		
		fseek(pFile,E_LFANEW + SECTIONNUMBER_OFFSET,0);
		iSectionNumber = readshort(pFile,0);

		fseek(pFile,SECTIONTABLE_OFFSET + (iSectionNumber -1) * SECTIONENTRYLENGTH + 0x14,0);
		iSectionBase = readlong(pFile,0);			
		Message("Section base in exe file is %x\n",iSectionBase);

		return iSectionBase;
		
}
//修正PE头信息
static PEHeaderCorrect(pFile)
{
		//关键处理,暂不外传!
		return 0;
}

static main()
{
	auto temp,i;
	auto startAddr, endAddr;
	auto countOR;
	auto pFile;
	auto strOutFileName;
	auto segStart;
	auto segEnd;
	auto iImageBase;
	auto iSectionAlignment;
	auto PEHeaderOffset;
	auto IATOffset;
	auto strIDBFilePath;
	auto iSectionBase;

	startAddr = MinEA();
	endAddr = MaxEA();
	iImageBase = FirstSeg() & 0xffff0000;
	iSectionAlignment = FirstSeg() & 0xffff;
	
	Message("Base:%x ,EP:%x , Min:%x  , Max:%x  \n",iImageBase,BeginEA(),MinEA(),MaxEA());
	
	strIDBFilePath = GetIDBFilePath();
	Message("idb file lies in %s\n",strIDBFilePath);
	
	strOutFileName = strIDBFilePath + "_dump.exe";

	pFile=fopen(strOutFileName,"w+b");
	
	PEHeaderOffset = BuildHeader(pFile,strIDBFilePath);
	if (PEHeaderOffset == -1)
		return -1;
		
	IATOffset = GetIATOffset(strIDBFilePath,PEHeaderOffset);
	if (IATOffset == -1)
		return -1;
		
	iSectionBase = RVA2FA(pFile);

	PatchIAT(iImageBase,iImageBase + IATOffset);
	
	for(i=startAddr;i<endAddr;)
	{
		segStart = GetSegmentAttr(i,SEGATTR_START);
		if(segStart == BADADDR) break;
		segEnd = GetSegmentAttr(i,SEGATTR_END);
		if(segEnd == BADADDR) break;		
		savefile(pFile, iSectionBase + segStart - iImageBase -iSectionAlignment,segStart,segEnd-segStart);
		Message("seg %x : %x : %x \n",GetSegmentAttr(i,SEGATTR_ALIGN),segStart,segEnd);
		i = segEnd + 1;
	}
	
	PEHeaderCorrect(pFile);
	
	fclose(pFile);
	
	return 0;
}

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 7
支持
分享
最新回复 (25)
雪    币: 291
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
可以从IDB的原始文件中恢复成EXE?太强大了吧
2010-1-6 22:26
0
雪    币: 1708
活跃值: (586)
能力值: ( LV15,RANK:670 )
在线值:
发帖
回帖
粉丝
3
so cool !
2010-1-6 22:35
0
雪    币: 255
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
自用版本这里公开吧
2010-1-7 10:23
0
雪    币: 1485
活跃值: (884)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
膜拜啊!
2010-1-7 16:28
0
雪    币: 433
活跃值: (1870)
能力值: ( LV17,RANK:1820 )
在线值:
发帖
回帖
粉丝
6
膜拜LZ!!!
2010-1-7 16:36
0
雪    币: 1450
活跃值: (35)
能力值: (RANK:680 )
在线值:
发帖
回帖
粉丝
7
thx LZ.
mark, 学习一下``
2010-1-7 17:15
0
雪    币: 147
活跃值: (11)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
8
LZ的强悍,不需要解释
2010-1-7 18:55
0
雪    币: 130
活跃值: (71)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
wonderful, you are awesome
2010-1-8 17:02
0
雪    币: 496
活跃值: (89)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
强大。收藏。
2010-1-8 21:11
0
雪    币: 134
活跃值: (84)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
11
太强大了,太暴力了
2010-1-9 20:44
0
雪    币: 4902
活跃值: (130)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
彪悍不需要理由
俺比较想知道暂不外传的那部分
2010-1-9 21:40
0
雪    币: 210
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
很强大,进来学习下。
2010-1-12 09:41
0
雪    币: 335
活跃值: (140)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
有何用处呢?
2010-1-12 18:07
0
雪    币: 107
活跃值: (404)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
这个还是要关注的........
2010-1-15 08:55
0
雪    币: 9791
活跃值: (2181)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
想要大大的自用版本啊!
2010-1-15 10:13
0
雪    币: 306
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
非常强大 无法膜拜了 直接**吧 用力顶
2010-4-8 11:37
0
雪    币: 58
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
膜拜下lz。。。。
2010-4-23 11:46
0
雪    币: 79
活跃值: (35)
能力值: ( LV2,RANK:150 )
在线值:
发帖
回帖
粉丝
19
我不明白,IDB生成EXE有什么价值
2010-5-22 20:42
0
雪    币: 205
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
不是一般的牛!是天牛!
2010-6-4 22:30
0
雪    币: 215
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
Mark !
2010-11-5 12:08
0
雪    币: 172
活跃值: (42)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
强大。。模拜。。可惜不完整
2011-2-8 18:08
0
雪    币: 234
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
23
在5.5中最后一个表项有多余96字节偏移
2011-2-23 08:38
0
雪    币: 154
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
膜拜
2011-2-23 08:43
0
雪    币: 53
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
同问....
2011-2-23 09:08
0
游客
登录 | 注册 方可回帖
返回
//