本质理解壳之 添加节

 

http://frfj.blogspot.com/2008/08/blog-post_26.html

 

代码含注释
流程如下:
1 将文件映射到内存得到基地址
2 检验PE标志
3 添加新节
3.1 增加节个数
3.2 得到文件对齐和节对齐值
3.3 通过节个数得到最后一节节头的地址和新节节头的地址
3.4 构建新节节头,包括name,Characteristics,misc.VirtualSize(实际大小),
通过VirtualSize文件对齐得到SizeOfRawData
3.5 通过最后一节节头VirtualAddress+VirtualSize节对齐后得到新节的VirtualAddress
通过最后一节节头PointerToRawData+SizeOfRawData文件对齐后得到新节PointerToRawData
3.6 修改SizeOfImage大小为新节的VirtualAddress+VirtualSize节对齐值
3.7 通过新节的PointerOfRawData(文件中的新节位置),将新节清0
4 修改 AddressOfEntryPoint, 旧的保存到新节最后, 新的指向新节首地址
5 将新节数据填充到新节中

 


.386
.model flat, stdcall
option casemap:none

include AddSection.Inc

APPEND_SIZE                     equ 2000h ;;添加到文件尾的大小

.const

g_szTargetFile    db 'target.exe', 0
g_szNewSectionName db ".cjay", 0
g_szOpenFileFailed      db "打不开文件", 0
g_szErr                 db "错误", 0
g_szDone      db "成功", 0
g_szDoneCap      db "Good Job", 0
g_szGetFileSizeFailed  db "获取文件大小失败", 0
g_szCreateMapFailed   db "创建文件映射失败", 0
g_szMapFileFailed   db "映射文件失败", 0
g_szInvalidPE    db "无效PE文件", 0

.data
g_bError   db 0 ;错误代码
g_dwNewSectionSize      dd 0 ;新节长度


;; 函数定义
CryptFile proto szFname : LPSTR ;;加密文件
AddSection proto pMem : LPVOID, pSectionName : LPVOID, dwSectionSize : DWORD ;; 添加新节
PEAlign proto dwTarNum : DWORD, dwAlignTo : DWORD ;;对齐

.code
Start:
  invoke CryptFile, offset g_szTargetFile
  invoke ExitProcess, 1

CryptFile proc szFname : LPSTR
  LOCAL hFile : HANDLE
  LOCAL hMap : HANDLE
     LOCAL pMem : LPVOID
     LOCAL dwOrigFileSize : DWORD ;;存放原始文件大小
     LOCAL dwNTHeaderAddr : DWORD ;;存放NT头地址
   
  xor eax, eax
  mov hFile, eax
  mov hMap, eax
  mov pMem, eax
 
  mov g_bError, al
  mov eax, offset EndNewSection - offset NewSection
  mov g_dwNewSectionSize, eax
 
  ;; open File
  invoke CreateFile,szFname, /
        GENERIC_READ+GENERIC_WRITE,/
        FILE_SHARE_READ+FILE_SHARE_WRITE,/
        NULL,/
   OPEN_EXISTING,/
        FILE_ATTRIBUTE_NORMAL,/
                     0
     .IF eax == INVALID_HANDLE_VALUE
       jmp OpenFileFailed
     .endif
  mov hFile, eax
 
  invoke GetFileSize, hFile, NULL
  .IF eax == 0
    jmp GetFileSizeFailed
  .endif   
 
  mov dwOrigFileSize, eax
  add eax, APPEND_SIZE
  xchg eax, ecx
 
  ;; create memory map
  xor ebx, ebx
  invoke CreateFileMapping, hFile, ebx, PAGE_READWRITE, ebx, ecx, ebx
  .IF eax == 0
    jmp CreateMapFailed
  .endif
  mov hMap, eax
 
  ;; map file to memory
  invoke MapViewOfFile, hMap, FILE_MAP_WRITE+FILE_MAP_READ+FILE_MAP_COPY,ebx,ebx,ebx
  .IF eax == 0
    jmp MapFileFailed
  .endif
  mov pMem, eax
 
  ;; check PE
  xchg eax, esi
  assume esi : ptr IMAGE_DOS_HEADER
  .IF [esi].e_magic != 'ZM'
    jmp InvalidPE
  .endif
  add esi, [esi].e_lfanew
  assume esi:ptr IMAGE_NT_HEADERS
  .IF word ptr [esi].Signature != 'EP'
    jmp InvalidPE
  .endif
  mov dwNTHeaderAddr, esi
 
  ;; add section
  invoke AddSection,pMem,offset g_szNewSectionName,g_dwNewSectionSize
  ;; return New Section Addr(VA)
  push eax
  mov esi, dwNTHeaderAddr
  assume esi : ptr IMAGE_NT_HEADERS
  ;;AddressOfEntryPoint
  mov ebx, dword ptr [esi].OptionalHeader.AddressOfEntryPoint
  add ebx, dword ptr [esi].OptionalHeader.ImageBase
  ;; Save the old entry
  mov eax, offset OrigAddressOfEntry
  mov dword ptr [eax], ebx
  ;; New Rntry is at New Section start
  pop eax
  assume eax : ptr IMAGE_SECTION_HEADER
  push dword ptr [eax].VirtualAddress
  pop dword ptr [esi].OptionalHeader.AddressOfEntryPoint
 
 mov esi, offset NewSection
 mov edi, dword ptr [eax].PointerToRawData
 add edi, pMem
 mov ecx, g_dwNewSectionSize
 cld
 rep movsb
 
LogicShellExit:
 ;; close handle & write it
 .IF pMem != NULL
  invoke UnmapViewOfFile, pMem
 .endif
 .IF hMap != NULL
  invoke CloseHandle, hMap
 .endif
     .IF hFile != NULL
       invoke CloseHandle, hFile
     .endif
     .IF g_bError == 0
        ;; show success message 
         invoke MessageBox, NULL, offset g_szDone, offset g_szDoneCap, MB_ICONINFORMATION
     .ENDIF       
     ret
;; ----- Show error message -----
OpenFileFailed:
     lea eax, g_szOpenFileFailed
     jmp ShowErr
GetFileSizeFailed:
     lea eax, g_szGetFileSizeFailed
     jmp ShowErr 
CreateMapFailed:
     lea eax, g_szCreateMapFailed
     jmp ShowErr
MapFileFailed:
     lea eax, g_szMapFileFailed
     jmp ShowErr
InvalidPE:         
     lea eax, g_szInvalidPE
     jmp ShowErr
ShowErr:
      invoke MessageBox, NULL, eax, offset g_szErr, MB_ICONERROR
      mov al, 1
      mov g_bError, al
      jmp LogicShellExit
;; ----- NEW SCETION-----
NewSection:
  call GetEip
GetEip:
  pop eax
  add eax, offset OrigAddressOfEntry - offset GetEip
  mov eax, dword ptr [eax]
  jmp eax
  OrigAddressOfEntry dd ?
EndNewSection:

CryptFile endp

AddSection proc uses ebx ecx edx esi edi, pMem:LPVOID, pSectionName:LPVOID, dwSectionSize:DWORD
  LOCAL dwNTHeader : LPVOID
  LOCAL dwFileAlign : DWORD ;文件对齐
  LOCAL  dwSecAlig : DWORD ;节对齐
  LOCAL dwLastSecTbl : DWORD ;最后一节地址(VA)   
  mov esi, pMem
  add esi, dword ptr [esi+03ch]
  mov dwNTHeader, esi
  assume esi : ptr IMAGE_NT_HEADERS
  mov cx, word ptr [esi].FileHeader.NumberOfSections
  movzx ecx, cx
  inc word ptr [esi].FileHeader.NumberOfSections
  push dword ptr [esi].OptionalHeader.FileAlignment
  pop dwFileAlign
  push dword ptr [esi].OptionalHeader.SectionAlignment
  pop dwSecAlig
 
  add esi, sizeof IMAGE_NT_HEADERS ;Section Header Base
  mov eax, sizeof IMAGE_SECTION_HEADER
  mov ebx, ecx
  imul ebx
  add esi, eax
 
  push esi
  sub esi, sizeof IMAGE_SECTION_HEADER
  mov dwLastSecTbl, esi
  pop esi ;; esi保存了新节地址
  ;; 设置新节
  assume esi : ptr IMAGE_SECTION_HEADER
  push esi
  lea edi, [esi].Name1
  mov esi, pSectionName
CopySectionNameLoop:
  lodsb
  test al, al
  jz EndCopySectionNameLoop
  stosb
  jmp CopySectionNameLoop
EndCopySectionNameLoop:
  pop esi
  ;;属性
  push 0E00000E0h
  pop dword ptr [esi].Characteristics
  ;;VirtualSize
  push dwSectionSize
  pop dword ptr [esi].Misc.VirtualSize
  ;;SizeOfRawdata
  invoke PEAlign, dwSectionSize, dwFileAlign
  mov dword ptr [esi].SizeOfRawData, eax
  ;;VirtualAddress, PointerToRawData
  mov eax, dwLastSecTbl
  assume eax : ptr IMAGE_SECTION_HEADER
  mov ecx, dword ptr [eax].VirtualAddress
  add ecx, dword ptr [eax].Misc.VirtualSize
  mov ebx, dword ptr [eax].PointerToRawData
  add ebx, dword ptr [eax].SizeOfRawData
 
  invoke PEAlign,ecx,dwSecAlig
  mov dword ptr [esi].VirtualAddress, eax
  invoke PEAlign,ebx,dwFileAlign
  mov dword ptr [esi].PointerToRawData, eax
  ;; SizeOfImage
  mov eax, dword ptr [esi].VirtualAddress
  add eax, dword ptr [esi].Misc.VirtualSize
  invoke PEAlign,eax,dwSecAlig
  mov edx, dwNTHeader
  assume edx : ptr IMAGE_NT_HEADERS
  mov dword ptr [edx].OptionalHeader.SizeOfImage, eax
 
  push dword ptr [esi].PointerToRawData
  pop edi
  add edi, pMem
  ;; clear new Section
  mov ecx, dwSectionSize
  xor eax, eax
  cld
  rep stosb
 
  ;; return New Section Address(VA)
  mov eax, esi
  assume esi : nothing
  assume eax : nothing
  assume edx : nothing
  ret
AddSection endp

PEAlign proc uses ecx edx, dwTarNum : DWORD, dwAlignTo : DWORD
  mov ecx, dwAlignTo
  mov eax, dwTarNum
  xor edx, edx
  div ecx
  cmp edx, 0 ;; edx保存余数
  jz AlreadyAligned
  inc eax
AlreadyAligned:
  mul ecx
  ret
PEAlign endp

end Start

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值