itprofes
Bạn có muốn phản ứng với tin nhắn này? Vui lòng đăng ký diễn đàn trong một vài cú nhấp chuột hoặc đăng nhập để tiếp tục.

Own extract overlay to a file

Go down

Own extract overlay to a file Empty Own extract overlay to a file

Bài gửi  admin 12/4/2010, 4:16 pm

Download: http://www.mediafire.com/?lvwxehdummg

Một overlay (aka extra-data) là một data đơn giản đựoc gắn vào physical image of một file thực thi Portable Executable. Giả sử ta lấy một file PE, gắn thêm một đọan các bytes (stuff) vào cuối bên trong file, và nó có một overlay. Vùng data này ko được định nghĩa như một phần của image bởi PE header và do vậy nó ko phải là một phần của virtual image of loaded PE.
Chú ý điều này:
DOS MZ header và stub (trong cấu trúc PE) ko được sử dụng nếu PE thực thi trong Windows, nhưng vùng e_lfanew field thì được sử dụng để định vị PE header. (Các bạn học thêm về cấu trúc file PE).

Một overlay ko phải là một phần của virtual image, vì vậy nó ko có address. Để tham chiếu đến nó bạn phải read nó từ physical image of file thực thi executable. Vì vậy để thực thi code bên trong một overlay bạn phải cấp phát động memory cho nó, đọc nó từ disk, rồi tạo một hàm gọi call đến offset thích hợp. Offset sẽ là tĩnh static, nhưng address sẽ thay đổi dựa trên base address of memory block chứa overlay, tương tự như RVAs và VAs.

Đối với PE overlays, ko có tài liệu liên quan hay bất cứ dữ liệu liên quan gì về nó, nó là một lọai dữ liệu đơn độc (proprietary nature) đính kèm theo file. Nó chỉ là extra data (dữ liệu đính kèm), ko có định dạng hay bất cứ gì được công bố.

Một vài năm trước phần lớn các ứng dụng mà nó sử dụng overlays để tham chiếu đến chúng bởi một static physical offset trong file. Điều này gây ra vấn đề với các executable packers khi static offset sẽ bị thay đổi. Cách thích hợp để tìm ra overlay, và bây giờ phần lớn các ứng dụng làm là dùng sum of last section's physical offset và last section's physical size. Chúng được tìm thấy trong object/section table.

Chú ý rằng một khi bạn (include) đính kèm extra-data/overlay trong PE section thì thực tế nó sẽ ko dài hơn overlay định trước, tức là chiều dài đọan extra-data sẽ cố định khi đứng đơn độc hay dính vào file.

Nếu bạn cần một tool để gắn extra data tại cuối of file, bạn có thể dùng bất kỳ Hex editor nào hay mỗi lệnh 'copy' command!

Chỉ cài đặt file được đặt tên là 'CopyOverlay.bat' với nội dụng như sau:

Code:
[FILE START]

@echo off
Set SourceFile=Main.exe
Set Ovl=Extended.ovl
Set Target=Main_Extended.exe
copy /B %SourceFile% + %Ovl% %Target% /B

[FILE END]
where:
SourceFile - your main executable
Ovl - overlay data
Target - main file with appended overlay




Như thế nào để code một tool tự động tìm và extract overlay? Nếu bạn nghiên cứu ImageDosHeader và ImageNtHeaders structures sẽ có tất cả thông tin bạn cần. Overlay chỉ là data sau Raw Offset + Raw Size of last section trong exe. Vì vậy, open exe file, tìm last section, add Raw Offset + Raw Size với file pointer và nếu filesize lớn hơn, thì sẽ có một overlay. Nếu size = filesize, thì ko có.

Vậy để save overlay bạn get offset như chi tiết ở trên và write như một file. Dễ dàng khi bạn sử dụng làm việc với các cấu trúc windows structures.

Ted.

Thực hành :

Bài ví dụ sau đây tôi viết bằng masm, nếu các bạn lập trình bằng ngôn ngữ khác thì tự chuyển đổi nhé.
Chương trình này có chức năng tự kết xuất ra phần extra-data mà nó đang mang theo.
Như trên ta thấy, các bạn có thể tự đính kèm một extra-data vào bất cứ một file exe nào bằng cách chạy file CopyOvarlay.bat. Vì vậy chúng ta sẽ lập trình một chương trình bình thường có chức năng tự kết xuất dữ liệu đính kèm. Sau đó biên dịch thành file overlay.exe. Dùng tip trên để gắn dữ liệu ăn theo vào file exe vừa biên dịch. Sau đó chạy file có overlay thì nó sẽ kết xuất ra extra-data thành một file độc lập.

Ghi chú : Phần code dưới đây chỉ có tính chất minh họa để học tập. Ko chuẩn mực về mặt lập trình cũng như ko kiểm tra các trường hợp erro bị lỗi có thể xảy ra (đừng có mà chê bai nhuể nhải nhe, nghe chán phèo, hehe).

Bây giờ chúng ta xem code:

File overlay.inc

Code:
include windows.inc
include kernel32.inc
include user32.inc

include \masm32\macros\macros.asm

includelib kernel32.lib
includelib user32.lib

include  \masm32\include\masm32.inc
includelib \masm32\lib\masm32.lib


.data

hinstance     dd 0     ; for own main program
hfile          dd 0   ; for temp file
file_handle    dd 0   ; for extract file

ddcommandline       dd 0
size_commandline    dd 0
size_currdir       dd 0

szFileName    db 512 dup (0)
szfilecopy    db "111xxx.exe",0
szvirus    db "virus1.exe",0
szFmt       db 'File size : %4X',0

ddfilesize        dd 0
ddfilesizeheader    dd 0
sizeoverlay       dd 0
      
buffertemp    db MAX_PATH dup (0)
buffer       db 512 dup (0)
buf       db 00h,00,00,00
OffsetPos    OVERLAPPED <NULL,NULL,5A0h,NULL,NULL>
 


.data?
numWriten  dd ?        ;Using in WriteFile
numReaded    dd ?

;===================================================


File ovarlay.asm

Code:
.386

.model flat, stdcall  ;32 bit memory model
option casemap :none  ;case sensitive

include overlay.inc

.code
start:

      
   invoke GetModuleHandle, NULL
   mov  hinstance,eax


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; get own file name   
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   invoke GetCommandLine
   mov ddcommandline,eax
   
   invoke lstrlen,ddcommandline   
   mov size_commandline,eax



   invoke GetCurrentDirectory,MAX_PATH,offset buffertemp
   
   invoke lstrlen, addr buffertemp
   mov size_currdir,eax
   
   mov eax,size_commandline
   sub eax,size_currdir
   sub eax,4
   
   mov ecx,size_currdir
   add ecx,2
      
   invoke szMid, ddcommandline,addr szFileName,ecx,eax
   
   invoke RtlZeroMemory, addr buffertemp, MAX_PATH

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; copy own file to a temp file named "111xxx.exe"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

   invoke CopyFile,offset szFileName,offset szfilecopy,1

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; get own file size from physical
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

   invoke CreateFile,offset szfilecopy,GENERIC_READ+GENERIC_WRITE,\
               FILE_SHARE_READ OR FILE_SHARE_WRITE,0,\
               OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0
   mov hfile,eax
   
   invoke GetFileSize,eax,0
   mov ddfilesize,eax
   

   
   mov eax,ddfilesize
   invoke wsprintf,addr buffer,offset szFmt, eax   
   invoke MessageBox,NULL,offset buffer,chr$("From physical disk"),MB_OK   
   invoke RtlZeroMemory, addr buffer, 512

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; get own file size from header
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

      mov    eax,hinstance
      mov    esi,[eax+3Ch]             
      add    esi,eax                       
      mov    edi,esi                      ; EDI = ESI = Ptr
                                                  ; to PE header
      movzx  eax,word ptr [edi+06h]        ; AX = n§ of sections

        dec    eax              ; AX-- sub 1 section to goto beginning
                             ; last section
        imul    eax,eax,28h                    ; EAX = AX*28
        add    esi,eax                        ; Normalize
        add    esi,78h                        ; Ptr to dir table
        mov    edx,[edi+74h]    ; EDX = n§ of dir entries
                                  ; (NumberOfRvaAndSizes)
        shl    edx,3                          ; EDX = EDX*8
        add    esi,edx                        ;esi ptr to beginning last setion

      mov eax,[esi+10h]
      add eax, [esi+14h]
      mov ddfilesizeheader,eax

      invoke wsprintf,addr buffer,offset szFmt, eax   
      invoke MessageBox,NULL,offset buffer,\
                            chr$("From file's header"),MB_OK   
      invoke RtlZeroMemory, addr buffer, 512
   
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;      Check overlay
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;   

mov eax,ddfilesize
sub eax,ddfilesizeheader
mov sizeoverlay,eax

.if (eax <= 1000) ;check everlay
   
   invoke CloseHandle,hfile   
   invoke DeleteFile,offset szfilecopy
   
   invoke MessageBox,NULL, chr$("Overlay not exist"),chr$("Notice"),MB_OK
   
.elseif
   
   invoke CreateFile,addr szvirus,\
                    FILE_ALL_ACCESS,\
                    0,\
                    NULL,\
                    CREATE_ALWAYS,\
                    0,\
                    NULL

                     mov file_handle,eax
               
               ;Extract overlay to a file
               
                    .if eax!=INVALID_HANDLE_VALUE
                        mov ebx,sizeoverlay
                        mov ecx,ddfilesizeheader
                       
                        .while ebx>0
                            
                             mov OffsetPos.loffset,ecx
                             push ecx
                             invoke ReadFile, hfile, ADDR buf, 1,\
                                          ADDR numReaded, ADDR OffsetPos
                            
                              invoke WriteFile,file_handle,\
                                      offset buf,1,addr numWriten,NULL
                              pop ecx                         
                              inc ecx
                              dec ebx                                                         
                      .endw

                        invoke CloseHandle,file_handle
                        invoke MessageBox,NULL,
                      chr$("Extract overlay to a file"),chr$("Tested"),\
                                      MB_OK
                    .elseif
                        invoke MessageBox,NULL,\
                              chr$("Cannot extract ovarlay to a file"),\
                                      chr$("Error"),MB_OK
                    .endif

   
   invoke CloseHandle,hfile   
   invoke DeleteFile,offset szfilecopy
      
.endif


   invoke ExitProcess,NULL

end start


Phân tích:

+Đầu tiên chúng ta lấy tên file đang chạy thông qua hai hàm API chính là GetCommandLine và GetCurrentDirectory. Cách này không chính qui lắm nhưng được cái là có tính chất anti debug. Các bạn tự tình hiểu tại sao nó lại anti được nhe. Vấn đề này là một đề tài riêng tôi sẽ đề cập trong một bài viết khác (nếu còn sung sức).


invoke GetModuleHandle, NULL
mov hinstance,eax


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; get own file name
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
invoke GetCommandLine
mov ddcommandline,eax

invoke lstrlen,ddcommandline
mov size_commandline,eax



invoke GetCurrentDirectory,MAX_PATH,offset buffertemp

invoke lstrlen, addr buffertemp
mov size_currdir,eax

mov eax,size_commandline
sub eax,size_currdir
sub eax,4

mov ecx,size_currdir
add ecx,2

invoke szMid, ddcommandline,addr szFileName,ecx,eax

invoke RtlZeroMemory, addr buffertemp, MAX_PATH


+Bước tiếp theo, sau khi có tên file, chúng ta sẽ copy chính file đang chạy thành một bản sao copy có tên mới là “111xxx.exe”. Ta dùng bản sao file này để tính kích thước vật lý của file và để copy dữ liệu đính kèm extra-data thành một file trích xuất .

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; copy own file to a temp file named "111xxx.exe"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

invoke CopyFile,offset szFileName,offset szfilecopy,1


+Với bản sao file exe này, chúng ta sẽ get size của nó thông qua hàm GetFileSize. Size này là size vật lý của file trên disk. Nếu file chưa gắn extra-data thì size này chính là size của file chương trình . Nếu file exe đã đuợc gắn extra-data thì size này bao gồm cả size file exe và cả extra-data.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; get own file size from physical
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

invoke CreateFile,offset szfilecopy,GENERIC_READ+GENERIC_WRITE,\
FILE_SHARE_READ OR FILE_SHARE_WRITE,0,\
OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0
mov hfile,eax

invoke GetFileSize,eax,0
mov ddfilesize,eax



mov eax,ddfilesize
invoke wsprintf,addr buffer,offset szFmt, eax
invoke MessageBox,NULL,offset buffer,chr$("From physical disk"),MB_OK
invoke RtlZeroMemory, addr buffer, 512


+Bây giờ chúng ta sẽ tính size của file chương trình, size này chính là size file exe (không có phần extra-data). Dựa vào trick trên trong phần lý thuyết chúng ta biết kích thước của một file PE có thể tính dựa vào phần header file như sau:
FileSize = PointerToRawData của section cuối cùng + SizeOfRawData của section cuối cùng.
Chú ý rằng, dù cho file exe có bị overlay hay không thì Header của file exe vẫn ko thay đổi. Và luôn tính được Filesize như trên.


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; get own file size from header
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

mov eax,hinstance
mov esi,[eax+3Ch]
add esi,eax
mov edi,esi ; EDI = ESI = Ptr to PE header
movzx eax,word ptr [edi+06h] ; AX = n§ of sections

dec eax ; AX-- sub 1 section to goto beginning
; last section
imul eax,eax,28h ; EAX = AX*28
add esi,eax ; Normalize
add esi,78h ; Ptr to dir table
mov edx,[edi+74h] ; EDX = n§ of dir entries (NumberOfRvaAndSizes)
shl edx,3 ; EDX = EDX*8
add esi,edx ;esi ptr to beginning last setion

mov eax,[esi+10h]
add eax, [esi+14h]
mov ddfilesizeheader,eax

invoke wsprintf,addr buffer,offset szFmt, eax
invoke MessageBox,NULL,offset buffer,chr$("From file's header"),MB_OK
invoke RtlZeroMemory, addr buffer, 512

+Sau khi ta tính ra các size file. Ta sẽ so sánh xem size file vật lý có bằng size file tính trên header không. Nếu bằng hay nhỏ hơn 1000 (1kb, vì một số trình biên dịch có độ lệnh nhỏ hơn 1kb) thì file này chưa bị gắn overlay. Nếu lớn hơn 1000 (1kb) thì file có phần overlay. Lúc này chúng ta sẽ tiến hành trích xuất extra-data. Trong phần code này chúng ta tính luôn size dữ liệu overlay để dùng sau này.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Check overlay
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

mov eax,ddfilesize
sub eax,ddfilesizeheader
mov sizeoverlay,eax

.if (eax <= 1000) ;check everlay

invoke CloseHandle,hfile
invoke DeleteFile,offset szfilecopy

invoke MessageBox,NULL, chr$("Overlay not exist"),chr$("Notice"),MB_OK

.elseif



+Đây là code trích xuất dữ liệu extra-data thành 1 file. Trước tiên ta cài đặt một file mới có tên là “virus1.exe” bằng hàm CreateFile. File này chính là file lưu extra-data. Sau đó ta dùng hàm ReadFile để đọc 1 byte từ file temp “111xxx.exe” cài đặt trước đó tại vị trí đầu tiên chứa dữ liệu extra-data vào biến buf. Và dùng hàm WriteFile để viết byte chứa trong biến buf vừa read vào file mới “virus1.exe”. Lần lược chúng ta sẽ chép các bytes từ phần dữ liệu overlay vào trong file virus1.exe thông qua vòng lặp while. Số lượng các bytes cần chép là sizeoverlay.

invoke CreateFile,addr szvirus,\
FILE_ALL_ACCESS,\
0,\
NULL,\
CREATE_ALWAYS,\
0,\
NULL

mov file_handle,eax

;Extract overlay to a file

.if eax!=INVALID_HANDLE_VALUE
mov ebx,sizeoverlay
mov ecx,ddfilesizeheader

.while ebx>0

mov OffsetPos.loffset,ecx
push ecx
invoke ReadFile, hfile, ADDR buf, 1,\
ADDR numReaded, ADDR OffsetPos

invoke WriteFile,file_handle,\
offset buf,1,addr numWriten,NULL
pop ecx
inc ecx
dec ebx
.endw

invoke CloseHandle,file_handle
invoke MessageBox,NULL,
chr$("Extract overlay to a file"),chr$("Tested"),\
MB_OK
.elseif
invoke MessageBox,NULL,\
chr$("Cannot extract ovarlay to a file"),\
chr$("Error"),MB_OK
.endif


invoke CloseHandle,hfile
invoke DeleteFile,offset szfilecopy

.endif


invoke ExitProcess,NULL


+Cuối cùng ta xóa file tạm temp “111xxx.exe” và close các handles. Thế là xong.

Sau khi code xong, chúng ta biên dịch file trên, tiếp theo gắn dữ liệu extra-data vào file vừa biên dịch như tip trên đề cập. Rồi chạy file có overlay đó xem sao. Sau khi chạy xong sẽ sinh ra một file virus1.exe đúng file dùng làm extra-data mà ta gắn kết vào file exe trước đó.
Chúc các bạn thành công.

Kết luận:

Code trên quả thật rất rườm rà. Thuộc hàng dỡm đời. Một số bước không cần thiết. Đồng thời cũng không check các lỗi hàm API có thể xảy ra (vì quá lười suy nghĩ tiếp). Nhưng dù sao, nó cũng có tính chất dùng để học tập và quan trọng là RUNNING. Cuối cùng, tôi muốn nhắc lại, trong code trên có một trick anti-debug các bạn tự tìm hiểu tạo sao nhe. Trick này hình như chưa ai sử dụng. Một lần nữa tôi mong muốn các bạn nên hòan chỉnh code trên và cùng chia sẽ cho cộng đồng.
Thanz u
admin
admin
Thiếu Úy III
Thiếu Úy III

Tổng số bài gửi : 627
Diem : 6546
Thank : 4
Join date : 24/03/2010
Đến từ : Bỉm Sơn - Thanh hóa

https://itprofes.forumvi.com

Về Đầu Trang Go down

Về Đầu Trang

- Similar topics

 
Permissions in this forum:
Bạn không có quyền trả lời bài viết