Section Settings
After version 0.2.0, micro uses the section/segment of ELF/PE/Mach-O files to obtain information, no longer using multiple builds.
Section mode supports configuration of limit, UPX compression (need to modify binary under ELF), digital signature, and allows modification of binary after building
File Structure
| ELF/PE/Mach-O Executable | INI settings | PHP or PHAR payload | Other data |
limit Configuration
If the following sfxsize section is not set:
micro_get_sfxsize_limit
returns 0, all data aftersize
is payloadmicro_get_sfxsize
returns, when- ELF: The end of the last Section, if there is no Section table, return the end of the last
Program Header Segment
- Mach-O: The end of
__LINKEDIT
- Windows: The end of the last Section
- ELF: The end of the last Section, if there is no Section table, return the end of the last
sfxsize section
The format of the sfxsize section is:
typedef struct _micro_sfxsize_section_t {
uint64_t size; /* sfx size, big endian */
uint64_t limit; /* limit size, big endian */
} __attribute__((pacaked)) micro_sfxsize_section_t;
size
represents the size of the executable file binary, in bytes, big endian
limit
represents the size of sfx binary + payload, in bytes, big endian
When limit
is 0, it means that there is no size limit, and all data after size
is payload
ELF
For systems that use ELF as the executable file format, such as Linux, FreeBSD:
micro obtains the above structure through the Section with .sh_name
as .sfxsize
Mach-O
For macOS’s Mach-O:
micro obtains the above structure through the __micro_sfxsize
Section of the __DATA
Segment
PE
For PE(EXE) format used by Windows:
micro obtains the above structure through the Section with ID as PHP_MICRO_SIGNATURE_ID
UPX
Under Windows, UPX compression is supported, and the compressed binary can be executed directly.
For ELF, because UPX discards the section table, it is impossible to obtain the real end position after UPX, so the binary needs to be modified:
Drop the data after the last Program Header Segment
after UPX compression, so that UPX cannot decompress it, making your program look like a virus.
For reference: Get last Program Header Segment
end position first
readelf -l micro.sfx.upxed
The output looks like:
...
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000001000 0x0000000001cb6f88 RW 0x1000
LOAD 0x0000000000000000 0x0000000001cb7000 0x0000000001cb7000
0x000000000065aadb 0x000000000065aadb R E 0x1000
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RW 0x10
...
Truncate the file to the largest Offset+FileSiz(0x0000000000000000 + 0x000000000065aadb = 6662875)
dd if=micro.sfx.upxed of=micro.sfx.upxed.stripped bs=6662875 count=1
chmod 0755 micro.sfx.upxed.stripped
Digital Signature
TODO: Make a tool to facilitate signing
Windows
The digital signature under Windows is to modify part of the PE/COFF header content (without changing the size), and then add some data at the end of the file, so the steps to refer to are:
- Modify sfx as desired, such as changing the logo to a favorite one, you can use Resource Hacker
- Add an
RC_DATA
with IDPHP_MICRO_SIGNATURE_ID
or12346
in sfx, size is 16 bytes, record the size of sfx at this time - Change the data of the section to real data (
.size
= sfx size,.limit
= sfx size + payload size, excluding the padding after), refer to the sfxsize section - Align the file to 4096 (512 seems enough, but I use 4096)
- Set the end of the last section to the end of the file
- Sign it
Mach-O
The digital signature under macOS is to add a segment/section, so the operation is:
- Concatenate sfx and payload
- Align to 4096
- Set the end of
__LINKEDIT
to the end of the file - Sign it