2017-02-03 14 views
5

tôi có chương trình C sau:Làm thế nào để tạo PE nhỏ (Win32) thực thi sử dụng MinGW

#include <windows.h> 
void __cdecl mainCRTStartup() { 
    DWORD bw; 
    HANDLE hfile = GetStdHandle(STD_OUTPUT_HANDLE); 
    WriteFile(hfile, "Hello, World!\r\n", 15, &bw, 0); 
    ExitProcess(0); /* Needed for successful (0) exit. */ 
} 

tôi biên dịch nó với GCC 4.8.2, sử dụng dòng lệnh sau:

i686-w64-mingw32-gcc -s -Os -fno-ident -fno-stack-protector -fomit-frame-pointer \ 
-fno-unwind-tables -fno-asynchronous-unwind-tables -falign-functions=1 \ 
-mpreferred-stack-boundary=2 -falign-jumps=1 -falign-loops=1 -mconsole \ 
-nostdlib -nodefaultlibs -nostartfiles -o h.exe h.c -lkernel32 

Tệp .exe được tạo dài 2048 byte. Làm thế nào tôi có thể làm cho nó nhỏ hơn bằng cách sử dụng MinGW, tốt nhất là tối đa 1024 byte, hoặc (thậm chí tốt hơn) tại nhiều nhất 512 byte?

Tôi muốn có giải pháp mà không cần viết mã lắp ráp, nhưng tôi cũng quan tâm đến các giải pháp lắp ráp.

Tôi đã thử -Wl,-N để giảm số lượng phần (phân đoạn), nhưng điều đó gây ra sự phân đoạn khi chạy .exe trong Wine.

Điều này article cho thấy rằng 480 byte là có thể. Cài đặt này sử dụng các cài đặt sau:

#pragma comment(linker, "/FILEALIGN:16") 
#pragma comment(linker, "/ALIGN:16")// Merge sections 
#pragma comment(linker, "/MERGE:.rdata=.data") 
#pragma comment(linker, "/MERGE:.text=.data") 
#pragma comment(linker, "/MERGE:.reloc=.data") 
#pragma optimize("gsy", on) 

Thật không may là #pragma không hoạt động với MinGW GCC. Có tương đương không?

Trong here Tôi có thể tìm thấy cờ GCC -Wl,--section-alignment,16,--file-alignment,16 làm giảm kích thước .exe xuống 752 byte. The .exe dường như làm việc trong Wine.

Bằng modifying the linker script Tôi có thể hợp nhất .data.rdata và giảm xuống 736 byte. Tôi đang sử dụng các cờ GCC này ngoài các cờ trên: -Wl,--section-alignment,16,--file-alignment,16,-T,tinygccpe.scr.

Tôi vẫn đang tìm kiếm số tiền tương đương MinGW là /MERGE.

This question tương tự, nhưng không cố gắng đi dưới 9000 byte.

Tôi cũng đang tìm kiếm một công cụ strip (lệnh strip trong MinGW không làm giảm kích thước .exe thêm nữa) mà có thể loại bỏ các cuống DOS (đó là giữa offsets 0x40 và 0x80, nó chứa This program cannot be run in DOS mode., chúng tôi có thể tiết kiệm 64 byte). This code có thể xóa nó, nhưng nó cũng phá vỡ tất cả các offsets tuyệt đối trong .exe. Thật không may, mối liên kết ld trong MinGW không thể xóa phần gốc DOS, nó được mã hóa cứng trong tệp bfd/peXXigen.c, ngay phía trên NT_SIGNATURE.

Có thể tách nhiều tiêu đề hơn khỏi tiêu đề .exe, tức là trình tải không sử dụng không?

+2

Bài viết được liên kết rất cũ. Đó là về VC++ 6, được phát hành vào năm 1998. Động lực để cố gắng tạo ra một nhị phân không có gì là cực nhỏ? Để làm bất cứ điều gì hiệu quả, bạn sẽ muốn liên kết trong một thư viện thời gian chạy, mà sẽ làm cho nhị phân của bạn lớn một lần nữa. Tôi chắc chắn không ủng hộ viết * bloated * code (rất chống lại điều đó, quá), nhưng bạn đang nghiêng tại cối xay gió ở đây, theo ý kiến ​​của tôi. Có nhiều lý do tại sao các trình liên kết chèn đệm vào và nó không quan trọng một khi bạn có số lượng mã không nhỏ. (Tuy nhiên, hãy bình chọn lên — đó là một câu hỏi khá hay.) –

+0

@Cody Grey: Động lực của tôi về tiết kiệm 1536 tiêu đề PE và byte soạn sẵn chủ yếu là học thuật. Những byte này có lẽ sẽ không mang lại lợi ích đáng kể cho người dùng với một hệ thống multi-gigabyte-RAM hiện đại. Tôi cũng đang phát triển một số chương trình với tổng số lượng mã nhỏ (nhỏ hơn 50 000 byte khi được biên dịch với các cài đặt ở trên). – pts

+1

Hãy nhớ rằng có kích thước cụm tối thiểu trên phương tiện lưu trữ. ví dụ. trên Windows, điều này thường là 4k. Ngay cả khi bạn quản lý để có được các mối liên kết để tạo ra một thực thi nhỏ hơn nó vẫn sẽ mất nhiều không gian trên đĩa. – greatwolf

Trả lời

0

Câu hỏi này có tài liệu trực tuyến rộng lớn, bắt đầu từ khoảng năm 1995.

Mỗi phiên bản của 32-bit và 64-bit của Windows có một bộ khác nhau của quy định về những gì giá trị tiêu đề họ chấp nhận trong thực thi .exe PE. Ví dụ: Windows XP từ chối các tệp .exe 32 bit có hàng nhập trừ khi chúng có ít nhất 3 phần và căn chỉnh phần của chúng là 4096 và liên kết tệp của chúng là 2 tối thiểu 512. (lệnh i686-w64-mingw32-gcc trong câu hỏi tạo ra như vậy thực thi.) Windows 7 chấp nhận các tệp .exe này, nhưng nó cũng chấp nhận tệp .exe với 0 phần, căn chỉnh phần 4, căn chỉnh tệp 4.

Có thể tạo tệp .exe nhỏ hơn 2048 byte.Ví dụ:

  • hh2.golden.exe (402 byte) hoạt động trên Windows XP, Windows 7 trở lên.
  • hh4.golden.exe (268 byte) không hoạt động trên Windows XP, nó hoạt động trên Windows 7 trở lên.
  • Mã nguồn lắp ráp được bao gồm trong repo pts-tinype.

Tệp .exe nhỏ hơn 268 byte chỉ hoạt động trên các phiên bản Windows cũ hơn Windows XP và chúng không hoạt động trên hệ thống Windows 64 bit.

văn học liên quan:

Các vấn đề liên quan