首页
社区
课程
招聘
[原创]loader的另一种思路。(PE实践)
发表于: 2005-6-8 22:38 15033

[原创]loader的另一种思路。(PE实践)

2005-6-8 22:38
15033

marxixing兄是我灵感的源泉,他写过这种loader,看的小弟一时兴起,也想做一个。顺便再回顾一下PE文件格式,以前看过好多遍只不过从没实践过,都忘的差不多了。
,在不在?
不要怪我盗窃你的思路哦
改天小弟给你倒茶赔罪行不?

好了,进入正题
marxixing兄做的loader是通过文件映射再创建挂起进程的方式实现的。
我的这个纯粹是从PE文件中修改,通过一个个指针,我指指指。。。。

有几个问题需要提一下:
1)。在使用fread( )后指针会后移。
2)。程序对那些经过人工修改过的程序会失败,比如把区块名去掉(OH,NO。。)
3)。由于本人菜,还没开发什么大的项目,所以对平台差异没考虑。。。
     所以如果有这方面问题都反馈给marxixing兄吧,

程序很简单,我也加了一些注释,大家浏览一下就可以了。

#include "stdafx.h"
#include <iostream.h>
#include <fstream.h>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
        if ( argc <= 1)
                exit(0) ;

        FILE *file ;
        if ( ( file = fopen( argv[1], "r+" ) ) == NULL )
        {
                cout << "ErrorCode:" << GetLastError() << endl ;
                exit (0) ;
        }

        //检测“MZ”标志
        char pDosHeadSign[2] ;
        fread ( &pDosHeadSign, 1, 2, file ) ;
        if ( !(pDosHeadSign[0] == 'M' && pDosHeadSign[1] == 'Z' ) )
        {
                cout << "Invaliable PE file!" << endl ;
                fclose ( file ) ;
                exit(0) ;
        }

        //定位到偏移文件头0X3C
        int result = fseek ( file, 0X3C, SEEK_SET ) ;
        if( result )
        {
                cout << "Seek file Error!" << endl ;
                fclose ( file ) ;
                exit (0) ;
        }

        //取得PEHead的偏移值
        DWORD pPEHeadOffset ;
        fread ( &pPEHeadOffset, sizeof(DWORD), 1, file ) ;

       
        //定位到PEHead,同时检测“PE”标志
        char pPEHeadSign[2] ;
        fseek ( file, pPEHeadOffset, SEEK_SET ) ;
        fread ( &pPEHeadSign, 2, 1, file ) ;
        if ( !( pPEHeadSign[0] == 'P' && pPEHeadSign[1] == 'E' ) )
        {
                cout << "Invaliable PE file!" << endl ;
                fclose ( file ) ;
                exit(0) ;
        }

        //取得区块数目, 由于前面取PE标志时已经后移两个字节 ==> pPEHeadOffset + 0X6 - 0X2 )
        WORD NumberOfSection ;
        fseek ( file, 0x4, SEEK_CUR ) ;
        fread ( &NumberOfSection, sizeof(WORD), 1, file ) ;
        cout << "NumberOfSection: " << NumberOfSection << endl ;

        //取得IMAGE_OPENTION_HEADER32结构的大小(pPEHeadOffset + 0X14 ) - 0X6 -0X2 == 0XC
        fseek ( file, 0XC, SEEK_CUR ) ;
        WORD SizeOfOptionalHeader ;
        fread ( &SizeOfOptionalHeader, sizeof(WORD), 1, file ) ;
        cout << "SizeOfOptionalHeader: 0X" << hex << SizeOfOptionalHeader << endl ;

        //取得程序执行的入口地址(RVA)(后移4个字节)
        //定位到 ( pPEHeadOffset + 0X28 ) -0X14 - sizeof(WORD) ==> 0X12
        fseek ( file, 0X12, SEEK_CUR ) ;
        DWORD AddressOfEntryPoint ;
        fread ( &AddressOfEntryPoint, sizeof(DWORD), 1, file ) ;
        cout << "AddressOfEntryPoint(RVA):0X" << hex << AddressOfEntryPoint << endl ;

        //定位到块表 ( pPEHeadOffset + SizeOfFileHead(0X18) + SizeOfOptionalHeader )
        DWORD SectionTableOffset = pPEHeadOffset + 0X18 + SizeOfOptionalHeader ;
        cout << "SectionTableOffset:0X" << hex << SectionTableOffset << endl ;
        fseek ( file, SectionTableOffset, SEEK_SET ) ;

        char SectionName[8] = {0} ;
        for ( int i = 0; i < NumberOfSection; i++ )
        {
                fread ( &SectionName, 8, 1, file ) ;

                if ( !strcmp( SectionName, ".text" ) )
                {
                        DWORD MemoryOffset, FileOffset, EntryPointFileOffset ;
                        fseek ( file, 4, SEEK_CUR ) ;
                        fread ( &MemoryOffset, sizeof(DWORD), 1, file ) ;

                        fseek ( file, 4, SEEK_CUR ) ;
                        fread ( &FileOffset, sizeof(DWORD), 1, file ) ;

                        EntryPointFileOffset = AddressOfEntryPoint - ( MemoryOffset - FileOffset ) ;
                        cout << "EntryPointFileOffset: 0X" << EntryPointFileOffset << endl ;

                        char EntryPointFirstByte ;
                        fseek ( file, EntryPointFileOffset, SEEK_SET ) ;
                        fread ( &EntryPointFirstByte, sizeof(char), 1, file ) ;
                        cout << "EntryPointFirstByte:0X" << hex << (int)EntryPointFirstByte ;
                        cout << "----" << "You shoud keep this value in mind!" << endl ;

                        byte Int3 = 0xCC ;
                        fseek ( file, EntryPointFileOffset, SEEK_SET ) ;
                        fwrite ( &Int3, sizeof(byte), 1, file ) ;
                        cout << "\"Int3\" insert success" << endl ;
                       
                        break ;
                }       
                else
                {
                        fseek ( file, 0X20, SEEK_CUR ) ;
                }       
        }

        fclose ( file ) ;

        cout << "Press \"ENTER\" key to leave...." << endl ;
        getchar();

        return 0 ;
}


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 7
支持
分享
最新回复 (13)
雪    币: 221
活跃值: (137)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
2
不懂,但也得支持呀。拿沙发坐一下
2005-6-8 22:44
0
雪    币: 216
活跃值: (370)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
3
老大,是loader不是lorder
一时以为你手误,
结果你满篇都是lorder
2005-6-8 22:45
0
雪    币: 1852
活跃值: (504)
能力值: (RANK:1010 )
在线值:
发帖
回帖
粉丝
4
我改

经常在同学面前自夸英语达到 “准8级”水准
今天终于露馅了
2005-6-8 22:46
0
雪    币: 50161
活跃值: (20630)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
5
最初由 北极星2003 发布
我改

经常在同学面前自夸英语达到 “准8级”水准
今天终于露馅了


8级水准太高,稍溢出点也正常。
2005-6-8 23:18
0
雪    币: 233
活跃值: (43)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
6
支持北极星2003兄,其实我这个思路也不完全是由我想出来的。是我看了LordPE的反汇编代码后照猫画虎做出来的。
运行了下编译后的程序,结果改变了原文件的入口点,这个好像不是loader的初衷吧。不过只要理解了思路,实现方法就无所谓了。让我们一起进步!
哪天见到了可是要喝茶的呀
2005-6-9 00:02
0
雪    币: 1852
活跃值: (504)
能力值: (RANK:1010 )
在线值:
发帖
回帖
粉丝
7
最初由 marxixing 发布

运行了下编译后的程序,结果改变了原文件的入口点,这个好像不是loader的初衷吧。不过只要理解了思路,实现方法就无所谓了。让我们一起进步!


这个是我的疏忽,loader应该只在内存中改变入口,而在磁盘文件中保持不变。
而我把磁盘文件也改了

看来标题应该叫“寻找程序入口点”了。。。

谢谢marxixing兄的鼓励,让我们一起进步。。。
2005-6-9 04:23
0
雪    币: 1223
活跃值: (469)
能力值: (RANK:460 )
在线值:
发帖
回帖
粉丝
8
不错
2005-6-9 09:49
0
雪    币: 328
活跃值: (925)
能力值: ( LV9,RANK:1010 )
在线值:
发帖
回帖
粉丝
9
不错,学习了!
2005-6-9 14:54
0
雪    币: 389
活跃值: (912)
能力值: ( LV9,RANK:770 )
在线值:
发帖
回帖
粉丝
10
学习,收藏。
2005-6-9 15:59
0
雪    币: 390
活跃值: (707)
能力值: ( LV12,RANK:650 )
在线值:
发帖
回帖
粉丝
11
最初由 goldenegg 发布
老大,是loader不是lorder
一时以为你手误,
结果你满篇都是lorder


估计他游戏打多了。要不就是LordPE用多了
2005-6-9 16:14
0
雪    币: 1852
活跃值: (504)
能力值: (RANK:1010 )
在线值:
发帖
回帖
粉丝
12
最初由 firstrose 发布


估计他游戏打多了。要不就是LordPE用多了


游戏嘛只对泡泡堂情有独钟
LordPE倒是常用
2005-6-9 17:33
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
北极星精力充沛,特发此帖,以此鼓励
2005-6-9 17:43
0
雪    币: 1852
活跃值: (504)
能力值: (RANK:1010 )
在线值:
发帖
回帖
粉丝
14
多谢多谢
2005-6-9 18:12
0
游客
登录 | 注册 方可回帖
返回
//