首页
社区
课程
招聘
[原创]简单壳之添加新节C语言实现
发表于: 2013-6-22 15:40 6625

[原创]简单壳之添加新节C语言实现

2013-6-22 15:40
6625

最近在学习PE方面的知识,想写个壳,但是发现看雪上讲得比较详细的与壳相关的文章都用汇编实现,我是小白对汇编只能看不会写,几经痛苦之后我终于实现了自己的C语言版的添加新节,希望对跟我一样的新手来说有所帮助哇。
我们还是先看看实现添加新节步骤哇:
1. 打开目标文件(CreateFile)
2. 将文件映射到内存(CreateFileMapping)
3. 获取内核对象基址(MapViewOfFile)
3.5. 判断是否是PE文件(略)
4. 得到最后一个SECTION的RVA
5. 得到新SECTION的RVA
6. 填写新节的相关信息
7. 根据新节头的数据写入节身数据
写文好痛苦啊,怎么感觉这么难

1~3:代码
BOOL ke::loadFile(LPCWSTR lpFileName)
{
        _tcscpy(BakFile,lpFileName);
        _tcscat(BakFile,L".exe");
        BOOL bTmp = CopyFile(lpFileName,BakFile,0);
        if(!bTmp){
                return FALSE;
        }

        hFile = CreateFile(BakFile,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN,0);
        if(hFile==INVALID_HANDLE_VALUE){
                return FALSE;
        }

        DWORD dwSize = GetFileSize(hFile,NULL);
        dwSize += 0x2000;

        hMap = CreateFileMapping(hFile,0,PAGE_READWRITE|SEC_COMMIT,0,dwSize,0);
        if(hMap==INVALID_HANDLE_VALUE){
                CloseHandle(hFile);
                return FALSE;
        }

        vBase = MapViewOfFile(hMap,FILE_MAP_ALL_ACCESS,0,0,0);
        if(vBase==NULL){
                CloseHandle(hFile);
                CloseHandle(hMap);
                return FALSE;
        }
        return TRUE;
}

4~5. 代码
pSectionHeader = (PIMAGE_SECTION_HEADER)GETSECTIONHEADER32(vBase);//指向节表的第一个节结构
pNewSection    = pSectionHeader + pNTHeaders->FileHeader.NumberOfSections;//指向新节
pLastSection   = pNewSection - 1;//新节前面的节

6.代码
pNewSection->Characteristics = IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE;//设置新节可读可写
        pNewSection->Misc.VirtualSize = dwSizeOfNewSection;//新节未对齐的大小
        strcpy((char*)pNewSection->Name,pszNewSectionName);//设置节名称
        pNewSection->PointerToRawData = pLastSection->PointerToRawData + pLastSection->SizeOfRawData;//设置节的文件偏移
        pNewSection->SizeOfRawData = align(pNewSection->Misc.VirtualSize,dwFileAlig);//节数据文件对齐后的大小
        //设置新节RVA
        pNewSection->VirtualAddress =  align(pLastSection->Misc.VirtualSize + pLastSection->VirtualAddress,dwSecAlig);
        pNTHeaders->OptionalHeader.AddressOfEntryPoint = pNewSection->VirtualAddress;//设置新入口点为新节RVA
        pNTHeaders->FileHeader.NumberOfSections++;//节数量加一
        //跟新镜像文件大小
        pNTHeaders->OptionalHeader.SizeOfImage = pNTHeaders->OptionalHeader.SizeOfImage + align(pNewSection->Misc.VirtualSize,dwSecAlig);

7.代码
dwOffset = pNewSection->PointerToRawData;
SetFilePointer(hFile,dwOffset,0,FILE_BEGIN);
WriteFile(hFile,&bMOV,x,&dwWritten,NULL);
WriteFile(hFile,&dwOldAddressOfEntry,y,&dwWritten,NULL);
WriteFile(hFile,&bJMP,z,&dwWritten,NULL);
WriteFile(hFile,&bEAX,w,&dwWritten,NULL);

主要代码,就这些了,第一次写文,可能会比较乱,贴的代码比较碎,完整的代码会传到附件,大家要是发现什么问题,要给我提出来哇,一起进步哈。


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

上传的附件:
收藏
免费 5
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//