首页
社区
课程
招聘
[原创]增加区段的VC嵌汇编代码
发表于: 2009-10-24 08:56 8213

[原创]增加区段的VC嵌汇编代码

2009-10-24 08:56
8213

// 增加区段.cpp : Defines the entry point for the console application.
//

#include <windows.h>
#include <stdio.h>
#include <winbase.h>

bool OpenMyFile(char fileName[]);
LPVOID AddSection(LPVOID ImageBase,char sectionName[],DWORD SectionNumber);
DWORD ToAlign(DWORD SectionNumber,DWORD AlignSize); //取整 第二个参数表示以多少进行取整

DWORD addNumber;  //新区段的字节数
DWORD VAValue;          //保存原入口VA值
char chao[MAX_PATH]="MessageBoxA GetProAddress LoadLibraryA user32.dll kernel32.dll";
DWORD addRess;    //保存GETMODULEHANDL地址

int main(int argc, char* argv[])
{
        addRess        =(DWORD)GetProcAddress(GetModuleHandle("kernel32.dll"),"GetModuleHandleA");

        addNumber = 100;

        char fileName[] = "text.exe";         //欲测试的程序
  

        if(!OpenMyFile(fileName))
                printf("failed!!!\n");

        return 0;
}

bool OpenMyFile(char fileName[])
{

        HANDLE hFile;
        hFile = CreateFile(fileName,                        //打开文件
                                        GENERIC_READ|GENERIC_WRITE,
                                        FILE_SHARE_READ|FILE_SHARE_WRITE,
                                        NULL,OPEN_EXISTING,
                                        FILE_ATTRIBUTE_NORMAL,
                                        NULL);
        if(!hFile)
                return false;
       
        DWORD fileSize = GetFileSize(hFile,NULL); //得到文件大小

        HANDLE hMap;
        hMap = CreateFileMapping(hFile,NULL,   
                                                        PAGE_READWRITE,0,
                                                        fileSize+0x2000,0);
       
        if(!hMap)
                return false;

        LPVOID ImageBase;
        ImageBase = MapViewOfFile(hMap,
                                                        FILE_MAP_ALL_ACCESS,
                                                        0,0,0);

        if(!ImageBase)
                return false;

        //判断是否为有效的PE文件
        PIMAGE_DOS_HEADER pDos;
        pDos = (PIMAGE_DOS_HEADER)ImageBase;
        if('ZM'!=pDos->e_magic)
                return false;

        PIMAGE_NT_HEADERS pNt;
        pNt = (PIMAGE_NT_HEADERS)((DWORD)ImageBase+pDos->e_lfanew);
        if('EP' !=pNt->Signature)
                return false;
       
        LPVOID newSectionName;   //指向新区段节名
        newSectionName = AddSection(ImageBase,".fan",addNumber);
        DWORD len = strlen(chao);   //把新区段要用到的字符COYP到其中
_asm
{
                mov esi,pNt
                mov ebx,dword ptr[esi+28h]   //入口RVA值
                add ebx,dword ptr[esi+34h]   //与映像值相加
                mov VAValue,ebx
                mov eax,newSectionName
                push dword ptr[eax+0ch]                 //得到新区段虚拟RVA
                pop dword ptr[esi+28h]       //修改到新入口
                mov ecx,dword ptr[esi+28h]   //把入口值加上字符串长度
                add ecx,len                                         //加上字符长度
                inc ecx
                add ecx,4                                         //加上原入口RVA值       
                add ecx,4                                         //加上GETMODULHAND地址的四个字节
                mov dword ptr[esi+28h],ecx
                lea esi,chao
                mov edi,dword ptr[eax+14h]
                add edi,ImageBase
                mov ecx,len
                inc ecx
                cld
                rep movs byte ptr[edi],byte ptr[esi]
               
                lea esi,addRess                                 //写入GETMODULEHANDLE的地址
                mov ecx,4
                cld
                rep movs byte ptr[edi],byte ptr[esi]

                lea esi,VAValue                                 //把原入口RVA值写到字符串后
                mov ecx,4
                cld
                rep movs byte ptr[edi],byte ptr[esi]
               
                lea esi,fan                                         //完成进入前原入口前的一些任务 如写病毒代码
                mov ecx,30h
                cld
                rep movs byte ptr[edi],byte ptr[esi]
               
}

        UnmapViewOfFile(ImageBase);
        CloseHandle(hMap);
        CloseHandle(hFile);

        return true;
fan:
        //在此处填写要在程序执行前想执行的代码
_asm
{       
            call zhi   //占五个字节
zhi:        pop ebx   
                sub ebx,5  //此时EBX指向 CALL ZHI这条指令
                sub ebx,4  //此时EBX指向存放原入口的RVA值
                push ebx       
       
                push ebp
                mov ebp,esp
                sub esp,10h //存放要用到的数据
       
                sub ebx,4
                mov esi,ebx
                sub ebx,0Dh
                push ebx                         //此时EBX指向KERNEL32 DLL字符串
                call dword ptr[esi]  //得到KERNEL32基址
                       
                add esp,10h                         //堆栈平衡       
                pop ebp
                pop ebx
                jmp dword ptr[ebx]    //跳回到原程序入口
                                       
}

}

LPVOID AddSection(LPVOID ImageBase,char sectionName[],DWORD SectionNumber)
{
                PIMAGE_NT_HEADERS pNt;
                DWORD fileAlign;   //文件对齐大小
                DWORD meryAlign;   //内存对齐大小
                LPVOID oldSection; //指向最后一个区段
                LPVOID newSection; //指向新的区段节表
   
  _asm
  {
                mov esi,ImageBase
                add esi,dword ptr[esi+3ch]
                mov pNt,esi       
                mov cx,word ptr[esi+6]
                movzx ecx,cx
                inc word ptr[esi+6]   //增加区段数目加一
                push dword ptr[esi+3ch]
                pop  fileAlign
                push dword ptr[esi+38h]
                pop meryAlign
                add esi,0F8h       //让ESI指向节表首地址
                mov eax,28h
                mov ebx,ecx
                imul ebx
                add esi,eax      //让ESI指向节表尾地址前
                mov newSection,esi
                sub esi,28h
                mov oldSection,esi
               
  }

         //以下是为新区段给名称
                int i=0;       
            char *newS =(char*)newSection;

                while(sectionName[i]!='\0')
                 {               
                        *newS=sectionName[i];
                        ++newS;       
                        ++i;
                 }

                //增加新区段其它信息
_asm
{  
            mov esi,newSection
                push 0E00000E0h
                pop dword ptr[esi+24h]
                push SectionNumber    //新区段的内存大小
                pop dword ptr[esi+8h]
               
}
               
        DWORD newFileSize =ToAlign(SectionNumber,fileAlign);  //新区段大小文件取整得到其文件大小
    _asm mov esi,newSection
        _asm mov eax,newFileSize
        _asm mov dword ptr[esi+10h],eax  //将新区段文件大小写到区段信息中

        //接下来就是写新区段的文件偏移和内存RVA值 这个值是根据原最后一个区段的信息算出的
_asm
{
    mov esi,oldSection
    mov ebx,dword ptr[esi+08h]    //虚拟大小
        add ebx,dword ptr[esi+0ch]        //虚拟偏移
    mov ecx,dword ptr[esi+10h]  //文件大小
        add ecx,dword ptr[esi+14h]        //文件偏移
        push fileAlign                                //文件取整
        push ecx
        call ToAlign
        add esp,8
        mov esi,newSection
        mov dword ptr[esi+14h],eax
        push meryAlign
        push ebx
        call ToAlign
        add esp,8
        mov dword ptr[esi+0ch],eax
//新区段RVA值加虚拟大小进行取整得新映像大小
        add eax,dword ptr[esi+08h]
        push meryAlign
        push eax
        call ToAlign
        add esp,8
        mov ebx,pNt
        mov dword ptr[ebx+50h],eax //修正映像大小
//新区段前SectionNumber个字节清零
        push dword ptr[esi+14h]
        pop edi
        add edi,ImageBase
        mov ecx,SectionNumber     //把新区段数据SectionNumber个字节置零
        xor eax,eax
        cld
        rep stos byte ptr[edi]
        mov eax,esi
       
}
                        
}

//区段取整
DWORD ToAlign(DWORD SectionNumber,DWORD AlignSize)
{

  DWORD size = SectionNumber%AlignSize;      //取余
  DWORD size2 = SectionNumber/AlignSize;         //取整
  if(size == 0)  //如果余数为0,则证明已是其整数倍
          return SectionNumber;
  else
      return (++size2)*AlignSize;

}

刚学,代码有点不整,大家见谅


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

上传的附件:
收藏
免费 7
支持
分享
最新回复 (13)
雪    币: 351
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
看了就要顶。。。
2009-10-26 12:12
0
雪    币: 253
活跃值: (89)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
刚开始学习PE资料,谢谢楼主。
2009-10-26 12:19
0
雪    币: 220
活跃值: (721)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
你加的这个区,怎么是写的附加数据?
2009-10-27 22:03
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
学习了 !!!
2009-11-4 12:04
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
真的很不错
2010-6-26 20:13
0
雪    币: 112
活跃值: (48)
能力值: ( LV9,RANK:320 )
在线值:
发帖
回帖
粉丝
7
额,,考虑不全面
2010-6-26 20:20
0
雪    币: 367
活跃值: (20)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
8
不知道M$何时加上X64等非X86的内联汇编支持,每次得额外写asm文件,不够清爽.
2010-6-29 07:25
0
雪    币: 38
活跃值: (52)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
9
mark it
2010-6-29 14:08
0
雪    币: 2323
活跃值: (4113)
能力值: ( LV12,RANK:530 )
在线值:
发帖
回帖
粉丝
10
不错!学习一下!!思路很好!
2010-7-14 16:27
0
雪    币: 20
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
mark!!!
现在正在看IAT
2010-8-28 00:48
0
雪    币: 33
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
顶有码的-------------------
2010-8-28 02:47
0
雪    币: 200
活跃值: (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
顶,不错,。
2010-8-28 12:19
0
雪    币: 2323
活跃值: (4113)
能力值: ( LV12,RANK:530 )
在线值:
发帖
回帖
粉丝
14
不错!很好!!
2010-8-29 17:18
0
游客
登录 | 注册 方可回帖
返回
//