【文章标题】: 一个超级简单的“壳”
【文章作者】: bithaha
【编写语言】: masm32
【使用工具】: radasm
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
不敢说原创,载入原输入表的代码几乎都是抄袭《软件加密技术内幕》上面的,谢谢看雪论坛出品如此好的一本书。
这个壳非常简单,对加壳以后的程序进行调试几乎发现不了壳的存在,汗一个。但是自己收获颇多。大家都喜欢说:来自看雪,回到看雪。
.386
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
include comdlg32.inc
includelib comdlg32.lib
IDC_EDIT1 EQU 1001
IDC_STATIC EQU 1002
IDC_PASS EQU 1003
ICO_ISCC EQU 1004
.data?
szFileName db MAX_PATH dup(?)
hFile dd ?
szBuffer db 1024h dup(?)
hInstance dd ?
ReadNumber dd ?
ReadBuffer dd ?
HeaderBuffer dd ?
peRva dd ? ;文件头在文件中的偏移地址
peshell dd ?
ShellSize dd ?
Rav_jiami1 dd ?
Size_jiami1 dd ?
FileSize dd ?
.const
lpstrFilter db 'All Files(*.*)',0,'*.*',0,0
szdlg db 'DLG_MAIN',0
.code
GetIntegral proc int1,int2;>>>>对齐数据
mov eax,int1
mov edx,0
div int2
mov eax,int1
sub eax,edx
add eax,int2
ret
GetIntegral endp
AddShell proc
invoke CreateFile,addr szFileName,GENERIC_READ or GENERIC_WRITE,FILE_SHARE_WRITE,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0
mov hFile ,eax
invoke GetFileSize,hFile,NULL
mov FileSize,eax
invoke SetFilePointer,hFile,3ch,0,0;3ch指向"pe"标志
invoke ReadFile,hFile,addr ReadBuffer,4,addr ReadNumber,0
mov ecx,ReadBuffer
mov peRva,ecx
add ecx,50h
invoke SetFilePointer,hFile,ecx,0,FILE_BEGIN
invoke ReadFile,hFile,addr ReadBuffer,4h,addr ReadNumber,0
invoke VirtualAlloc,NULL,addr ReadBuffer,MEM_COMMIT,PAGE_READWRITE
mov HeaderBuffer,eax
invoke SetFilePointer,hFile,0,0,FILE_BEGIN
invoke ReadFile,hFile,HeaderBuffer,addr ReadBuffer,addr ReadNumber,0
mov ecx,HeaderBuffer
add ecx,peRva
mov esi,ecx
movzx ecx,word ptr [esi+6h];NumberOfSections
movzx edi,word ptr [esi+14h];IMAGE_OPTIONAL_HEADER32结构的大小
add edi,esi
add edi,18h;esi--->pe头的位置,edi---->节表的位置
GetSections:
.repeat
push ecx
or dword ptr [edi+24h],0c0000000h
mov eax,dword ptr [edi+14h];eax--->节在文件中的偏移
invoke SetFilePointer,hFile,eax,NULL,FILE_BEGIN
mov ebx,dword ptr [edi+0ch];edi+0c--->该节的rva
add ebx,HeaderBuffer
mov ecx,dword ptr [edi+10h];在文件中对齐的尺寸
invoke ReadFile,hFile,ebx,ecx,addr ReadNumber,0
cmp dword ptr [edi],'xet.'
jz jiami;加密.text段
add edi,28h
pop ecx
dec ecx
jcxz next
jmp GetSections
;>>>>>>>>>>>>>>>>>>>>>>>>>加密text节>>>>>>>>>>>>>>>>>>>>>>>>>>
jiami:
mov ecx,dword ptr [edi+10h]
mov ebx,dword ptr [edi+0ch]
add ebx,HeaderBuffer
jiami_loop:
xor byte ptr [ebx],13h
inc ebx
loop jiami_loop
mov ebx,dword ptr [edi+14h]
invoke SetFilePointer,hFile,ebx,NULL,FILE_BEGIN
mov ecx,dword ptr [edi+10h]
mov ebx,dword ptr [edi+0ch]
add ebx,HeaderBuffer
invoke WriteFile,hFile,ebx,ecx,addr ReadNumber,NULL;写入文件
mov eax,dword ptr [edi+0ch]
mov Rav_jiami1,eax
mov ecx,dword ptr [edi+10h]
mov Size_jiami1,ecx
add edi,28h
pop ecx
dec ecx
jcxz next
.until FALSE
next:
push edi ;新快表起点
;>>>>>>>>>>>>>>>>>>>>>>>>保存相关信息>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;把部分数据保存到壳中
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
push esi
invoke VirtualAlloc,NULL,2000h,MEM_COMMIT ,PAGE_READWRITE
mov peshell,eax
lea esi,shellstart
mov ecx,shellend-shellstart
mov edi,peshell
rep movsb
pop esi;esi---->pe头的位置
mov edi,peshell
add edi,OEP-shellstart
mov eax,dword ptr [esi+28h];原文件OEP
mov dword ptr [edi],eax;保存OEP RVA
mov edi,peshell
add edi,Import-shellstart
mov eax,dword ptr [esi+80h]
mov dword ptr [edi],eax;保存输入表RVA
mov edi,peshell
add edi,RVA_jiami-shellstart
mov eax,Rav_jiami1;加密段的rva
mov dword ptr [edi],eax
mov eax,Size_jiami1
mov edi,peshell
add edi,SIZE_jiami-shellstart
mov dword ptr [edi],eax
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;添加新节
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
pop edi
mov dword ptr [edi],'csi.'
mov ecx,shellend-shellstart
invoke GetIntegral,ecx,dword ptr [esi+38h];esi+38h------->在内存中的对齐粒度
mov dword ptr [edi+08h],eax
mov eax,dword ptr [esi+50h];esi+50h---------->内存中整个pe文件尺寸
mov dword ptr [edi+0ch],eax;----------->等于新节的rva
invoke GetIntegral,ecx,dword ptr [esi+3ch];esi+38h--------->文件中的对其粒度
mov dword ptr [edi+10h],eax
mov ShellSize,eax
mov eax,dword ptr [edi-14h]
add eax,dword ptr [edi-18h]
mov dword ptr [edi+14h],eax
mov dword ptr [edi+24h],0c0000040h
inc word ptr [esi+6h]
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;修改相关文件头
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
mov eax,dword ptr [edi+0ch]
mov dword ptr [esi+28h],eax;修改Oep
invoke GetIntegral,ecx,dword ptr [esi+38h]
add eax,dword ptr [esi+50h]
mov ebx,dword ptr [esi+50h]
mov dword ptr [esi+50h],eax
mov eax,ebx
add eax,ImportTable-shellstart
mov dword ptr [esi+80h],eax
mov dword ptr [esi+7ch],ImportTableend-ImportTable
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;修改外壳输入表部分相对地址
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
mov ecx,dword ptr [esi+80h]
mov eax,peshell
add eax,ImportTable-shellstart
add dword ptr [eax],ecx
mov eax,peshell
add eax,Import_Name-shellstart
add dword ptr [eax],ecx
mov eax,peshell
add eax,Import_FirstThunk-shellstart
add dword ptr [eax],ecx
mov eax,peshell
add eax,THUNK_DATA1-shellstart
add dword ptr [eax],ecx
mov eax,peshell
add eax,THUNK_DATA2-shellstart
add dword ptr [eax],ecx
mov eax,peshell
add eax,THUNK_DATA3-shellstart
add dword ptr [eax],ecx
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;把外壳写入文件,把修改的文件头写入文件
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
mov ecx,ShellSize
invoke SetFilePointer,hFile, ecx,0,FILE_END
invoke SetEndOfFile,hFile
mov eax,FileSize
invoke SetFilePointer,hFile,eax,0,FILE_BEGIN
invoke WriteFile,hFile,peshell,ecx,addr ReadNumber,0
invoke SetFilePointer,hFile,0,0,FILE_BEGIN
invoke WriteFile,hFile,HeaderBuffer,dword ptr [esi+54h],addr ReadNumber,0
invoke CloseHandle,hFile
invoke VirtualFree,peshell,0,MEM_RELEASE
invoke VirtualFree,HeaderBuffer,0,MEM_RELEASE
ret
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>pe外壳程序>>>>>>>>>>>>>>>>>>>>>>>>
shellstart: ;shell开始
call @@1
ImportTable dd THUNK_DATA1-ImportTable
dd 0,0
Import_Name dd DllName-ImportTable
Import_FirstThunk dd THUNK_DATA1-ImportTable
dd 0,0,0,0,0
THUNK_DATA1 dd IMPORT_BY_NAME1-ImportTable
THUNK_DATA2 dd IMPORT_BY_NAME2-ImportTable
THUNK_DATA3 dd IMPORT_BY_NAME3-ImportTable
dd 0
DllName db 'Kernel32.dll',0
IMPORT_BY_NAME1 dw 0
db 'GetProcAddress',0
IMPORT_BY_NAME2 dw 0
db 'GetModuleHandleA',0
IMPORT_BY_NAME3 dw 0
db 'LoadLibraryA',0
ImportTableend:
;>>>>>>>>>>>>>>>>>>>>>>>>>以上为输入表结构>>>>>>>>>>>>>>>>>>>>>>>>>>
;在把壳写入文件时,需要重新定位以上信息>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;ebp中保存着要加壳文件的shellstart的地址(不是相对虚拟地址,而是绝对)
@@1:
pop ebp;此时ebp中为ImportTable的地址
sub ebp,(ImportTable-shellstart)
mov edi, dword ptr [ebp+(RVA_jiami-shellstart)]
push 0
call dword ptr [ebp+(THUNK_DATA2-shellstart)]
add edi,eax
mov dword ptr [ebp+(handle-shellstart)],eax
mov ecx, dword ptr [ebp+(SIZE_jiami-shellstart)]
jiemi:
xor byte ptr [edi],13h
inc edi
loop jiemi
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>初始化输入表>>>>>>>>>>>>>>>>>>>>>>>>>>>>
mov edi,dword ptr [ebp+(Import-shellstart)]
push 0
call dword ptr [ebp+(THUNK_DATA2-shellstart)]
mov dword ptr [ebp+(handle-shellstart)],eax
add edi,dword ptr [ebp+(handle-shellstart)]
GetDllAddr:
mov esi,dword ptr [edi+0ch];esi--->dllname的rva
.if esi==0
jmp DllFinish
.endif
add esi,dword ptr [ebp+(handle-shellstart)]
push esi
call dword ptr [ebp+(THUNK_DATA2-shellstart)];获取dll句柄
.if eax==0
push esi
call dword ptr [ebp+(THUNK_DATA3-shellstart)]
.endif
mov esi,eax
mov edx,dword ptr [edi]
.if edx==0
mov edx,dword ptr [edi+10h]
.endif
add edx,dword ptr [ebp+ (handle-shellstart)]
mov ebx,dword ptr [edi+10h]
add ebx,dword ptr [ebp+(handle-shellstart)]
GetFuncAddr:
mov eax,dword ptr [edx] ;IMAGE_THUNK_DATA
cmp eax,0
jz FunctionFinish
push ebx
push edx
cdq
.if edx==0
add eax,2h
add eax,dword ptr [ebp+(handle-shellstart)]
.else
and eax,7fffffffh
.endif
push eax
push esi;dll句柄
call dword ptr [ebp+(THUNK_DATA1-shellstart)]
mov dword ptr [ebx],eax
pop edx
pop ebx
add edx,4h
add ebx,4h
jmp GetFuncAddr
FunctionFinish:
add edi,14h
jmp GetDllAddr
DllFinish:
mov eax,dword ptr [ebp+(OEP-shellstart)]
add eax,dword ptr [ebp+(handle-shellstart)]
mov ebp,esp
push ebp
add esp,1
inc ecx
nop
dec ecx
pop ebp
add esp,-1
nop
push eax
retn
RVA_jiami DD 0
SIZE_jiami DD 0
Import DD 0
handle DD 0
OEP DD 0
shellend:
AddShell endp
_DlgProcMain proc uses ebx edi esi hWnd,wMsg,wParam,lParam
local @lpfn:OPENFILENAME
local @dwBytesRead:dword
invoke RtlZeroMemory,addr @lpfn,sizeof @lpfn
mov eax,wMsg
.if eax==WM_CLOSE
invoke EndDialog,hWnd,NULL
.elseif eax==WM_INITDIALOG
invoke LoadString,hInstance,szErr101,addr szErr,sizeof szErr
invoke LoadString,hInstance,szPass102,addr szPass,sizeof szPass
invoke LoadString,hInstance,szStop103,addr szStop,sizeof szStop
invoke LoadIcon,hInstance,ICO_ISCC
invoke SendMessage,hWnd,WM_SETICON,ICO_ISCC,eax
invoke GetDlgItem,hWnd,IDC_PASS
invoke EnableWindow,eax,FALSE
.elseif eax==WM_COMMAND
mov eax,wParam
.if ax==IDOK
mov @lpfn.lStructSize,sizeof @lpfn
push hWnd
pop @lpfn.hWndOwner
mov @lpfn.lpstrFilter,offset lpstrFilter
mov @lpfn.lpstrFile,offset szFileName
mov @lpfn.nMaxFile,MAX_PATH
mov @lpfn.Flags,OFN_FILEMUSTEXIST or OFN_PATHMUSTEXIST
invoke GetOpenFileName,addr @lpfn
.if eax
invoke SetDlgItemText,hWnd,IDC_EDIT1,addr szFileName
invoke GetDlgItem,hWnd,IDC_PASS
invoke EnableWindow,eax,TRUE
.endif
.elseif ax==IDC_PASS
invoke GetDlgItemText,hWnd,IDC_EDIT1,addr szFileName,MAX_PATH
call AddShell
.endif
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
_DlgProcMain endp
start:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance, addr szdlg,NULL,addr _DlgProcMain,NULL
invoke ExitProcess,eax
end start
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
2007年05月13日 下午 06:23:02
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)