Hôm trước mình lượn web kiếm đc phần mềm cho phép 32bit App sử dụng trên 2Gb trên Win 64bit. Mình tò mò và đã tìm hiểu cách hoạt động của nó. Hôm nay chia sẻ với anh em.

Mục đích chính của bài viết là phát triển phần mềm. Nó cũng chả to lớn gì, nhưng mong bạn nào leech thì ghi nguồn.

Các bạn có thể down phần mềm ở phần đính kèm.
Ngắn gọn vậy thôi , bây h ta đi trả lời câu hỏi How do they do it ?

Sau khi load phần mềm vào OllyDbg , ta trace đến đoạn này



Nó có nhiệm vụ sau :

Mã:
  EAX = GetOpenFileNameW( &Local_149 ) ; // 4011CE , 4011DD , 4011FA  if( EAX != 0 ) // GetOpenFileNameW thành công. 401200 , 401202  {                         4gb_patch.00401087 ( &Local_149 ) ; // 401209 , 40120F , 401210  }  return;
Bên trong hàm 4gb_patch.00401087 :


Đoạn từ 4010A1 đến 4010AD có nhiệm vụ thêm “.Backup” vào cuối chuỗi Local_149 và lưu chuỗi mới vào Local_132.


Mã:
Local_132 = strcat(&Local_149 , L“.Backup” ) ;


Đoạn trên có nhiệm vụ tạo file backup :


Mã:
CopyFileW( &Local_149 , &Local_132 , TRUE) ; // ARG.1 là tham số vào của hàm 4gb_patc.00401087 và cũng là Local_149.


Đoạn trên có nhiệm vụ mở file đã chọn :


Mã:
hFile  = CreatFileW( &Local_149 , GENERIC_READ|GENERIC_WRITE , FILE_SHARE_READ , NULL , OPEN_EXISTING , NORMAL , NULL);



Mã:
DWORD dwFileSize = GetFileSize( hFile , NULL );


Đoạn trên có nhiệm vụ so sánh dwFileSize với 8000h , nếu <= 8000h thì lấy nó làm Size để cấp phát luôn, còn > 8000h thì chỉ cấp phát Size = 8000h thôi. ( 8000h bytes = 32 kb ).


Mã:
VirtualAlloc( NULL, Size , MEM_COMMIT , PAGE_READWRITE ) ;ReadFile (hFile , Buffer , Size , &pBytesRead , NULL );



Mã:
SetFilePointer( hFIle , 0 , NULL , FILE_BEGIN );


Đoạn trên có nhiệm vụ sau:
Lúc đó , EDI = 3F0000 ,là còn trỏ Buffer do hàm VirtualAlloc cấp phát và đã được ghi vào bởi hàm ReadFile. Vậy EDI = 3F0000 là điểm khởi đầu của File đã chọn.
Chuyển 4 bytes từ EDI + 3C = 3F003C vào EAX . Để hiểu được đoạn này cần có hiểu biết về PE file format.



IMAGE_DOS_HEADER là cấu trúc nằm ở trên cùng 1 PE file.
Cấu trúc nó có dạng:



Mã:
->DOS Header
    e_magic:     0x5A4D  
    e_cblp:      0x0090  
    e_cp:        0x0003  
    e_crlc:      0x0000  
    e_cparhdr:   0x0004  
    e_minalloc:  0x0000  
    e_maxalloc:  0xFFFF  
    e_ss:        0x0000  
    e_sp:        0x00B8  
    e_csum:      0x0000  
    e_ip:        0x0000  
    e_cs:        0x0000  
    e_lfarlc:    0x0040  
    e_ovno:      0x0000  
    e_res:       0x0000000000000000  
    e_oemid:     0x0000  
    e_oeminfo:   0x0000  
    e_res2:      0x0000000000000000000000000000000000000000  
    e_lfanew:    0x000000E0
Cấu trúc này có kích cỡ 64 bytes, 3C = 60 sẽ trỏ tới e_lfanew , giá trị DWORD này là offset để tới IMAGE_NT_HEADER. => EAX sẽ chứa điểm khởi đầu của IMAGE_NT_HEADER sau khi + EDI.


Mã:
->File Header  
    Machine:               0x014C  (I386)  
    NumberOfSections:      0x0003  
    TimeDateStamp:         0x3B7D8476  (GMT: Fri Aug 17 20:54:14 2001)  
    PointerToSymbolTable:  0x00000000  
    NumberOfSymbols:       0x00000000  
    SizeOfOptionalHeader:  0x00E0  
    Characteristics:       0x010F
                           (RELOCS_STRIPPED)  
                           (EXECUTABLE_IMAGE)  
                           (LINE_NUMS_STRIPPED)  
                           (LOCAL_SYMS_STRIPPED)  
                           (32BIT_MACHINE)
Trừ 4 bytes của Signature ta còn 22 ( 16h ) – 4 = 18. Từ điểm khởi đầu của cấu trúc

IMAGE_FILE_HEADER + 18 = Characteristics.


Lúc đó Characteristics = 10Fh tương ứng với các thông số như trên.
Chương trình sẽ cho Characteristics = Characteristics OR 20h = 12Fh sẽ có các thông số sau :




Vậy nó thêm thông số Large address aware.



Mã:
WriteFile(hFile , Buffer, Size , &BytesWritten , NULL ) ;CloseHandle(hFile);
Tuyệt , nó thêm mỗi cờ Large address aware là có thể cho phép 32bit App sử dụng memory như 64bit App ? Why ?

Bài viết chỉ trả lời câu hỏi How ? và phần của các bạn là trả lời Why ?