Linux рдХреЗ рд▓рд┐рдП x86_64 ELF рдлрд╝рд╛рдЗрд▓ рдкреИрдХрд░ рдмрдирд╛рдирд╛

рдкрд░рд┐рдЪрдп


рдпрд╣ рдкреЛрд╕реНрдЯ linux x86_64 рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд░рд▓ рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдлрд╝рд╛рдЗрд▓ рдкреИрдХрд░ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХрд╛ рд╡рд░реНрдгрди рдХрд░реЗрдЧреАред рдпрд╣ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рдкрд╛рдардХ рд╕реА рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛, x86_64 рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдХреЗ рд▓рд┐рдП рдЕрд╕реЗрдВрдмрд▓реА рднрд╛рд╖рд╛ рдФрд░ рдбрд┐рд╡рд╛рдЗрд╕ рдИрдПрд╕рдЖрдИ рдлрд╛рдЗрд▓реЛрдВ рдХреЗ рд╕рд╛рде рдкрд░рд┐рдЪрд┐рдд рд╣реИред рд╕реНрдкрд╖реНрдЯрддрд╛ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд▓реЗрдЦ рдореЗрдВ рддреНрд░реБрдЯрд┐ рд╕реЗ рдирд┐рдкрдЯрдиреЗ рдХреЛ рдХреЛрдб рд╕реЗ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдФрд░ рдХреБрдЫ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдирд╣реАрдВ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рдерд╛, рдкреВрд░рд╛ рдХреЛрдб рдЬреАрдердм ( рд▓реЛрдбрд░ , рдкреИрдХрд░ ) рдХреЗ рд▓рд┐рдВрдХ рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░рдХреЗ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рд╡рд┐рдЪрд╛рд░ рдпрд╣ рд╣реИ: рд╣рдо ELF рдлрд╝рд╛рдЗрд▓ рдХреЛ рдкреИрдХрд░ рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рд╣рдореЗрдВ рдЖрдЙрдЯрдкреБрдЯ рдкрд░ рдирд┐рдореНрди рд╕рдВрд░рдЪрдирд╛ рдХреЗ рд╕рд╛рде рдПрдХ рдирдпрд╛ рдорд┐рд▓рддрд╛ рд╣реИ:
рдИрдПрд▓рдПрдл рд╣реЗрдбрд░
рдХрд╛рд░реНрдпрдХреНрд░рдо рдХрд╛ рд╢реАрд░реНрд╖рдХ
рдХреЛрдб рд╕реЗрдЧрдореЗрдВрдЯрдкреИрдХреЗрдЬреНрдб рдИрдПрд▓рдПрдл рдлрд╛рдЗрд▓ рдбрд╛рдЙрдирд▓реЛрдбрд░
рдкреИрдХреНрдб ELF рдлрд╝рд╛рдЗрд▓
рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рдбреЗрдЯрд╛ рдХреЗ 256 рдмрд╛рдЗрдЯреНрд╕

рд╕рдВрдкреАрдбрд╝рди рдХреЗ рд▓рд┐рдП, рд╣рдлрд╝рдореИрди рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдПрдиреНрдХреНрд░рд┐рдкреНрд╢рди рдХреЗ рд▓рд┐рдП - рдПрдИрдПрд╕-рд╕реАрдЯреАрдЖрд░ рдПрдХ 256-рдмрд┐рдЯ рдХреБрдВрдЬреА рдХреЗ рд╕рд╛рде, рдЕрд░реНрдерд╛рддреН рдХреЛрдХреЗрдХ рдЯрд╛рдЗрди -рдПрдИрдПрд╕-рд╕реА рд╕реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрдиред рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рдбреЗрдЯрд╛ рдХреЗ 256 рдмрд╛рдЗрдЯреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдПрдИрдПрд╕ рдХреБрдВрдЬреА рдФрд░ рдЖрд░рдВрднреАрдХрд░рдг рд╡реЗрдХреНрдЯрд░ рдХреЛ рдЫрджреНрдо рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рд╕рдВрдЦреНрдпрд╛ рдЬрдирд░реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреИрд╕рд╛ рдХрд┐ рдиреАрдЪреЗ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ:

for(int i = 0; i < 32; i++) { seed = (1103515245*seed + 12345) % 256; key[i] = buf[seed]; } 

рдпрд╣ рдирд┐рд░реНрдгрдп рд░рд┐рд╡рд░реНрд╕ рдЗрдВрдЬреАрдирд┐рдпрд░рд┐рдВрдЧ рдХреЛ рдЬрдЯрд┐рд▓ рдмрдирд╛рдиреЗ рдХреА рдЗрдЪреНрдЫрд╛ рдХреЗ рдХрд╛рд░рдг рд╣реБрдЖ рдерд╛ред рдЖрдЬ рддрдХ, рдореИрдВрдиреЗ рдорд╣рд╕реВрд╕ рдХрд┐рдпрд╛ рдХрд┐ рдЬрдЯрд┐рд▓рддрд╛ рдирд┐рд░рд░реНрдердХ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВрдиреЗ рдЗрд╕реЗ рджреВрд░ рдХрд░рдирд╛ рд╢реБрд░реВ рдирд╣реАрдВ рдХрд┐рдпрд╛, рдХреНрдпреЛрдВрдХрд┐ рдореИрдВ рдЙрд╕ рдкрд░ рд╕рдордп рдФрд░ рдКрд░реНрдЬрд╛ рдЦрд░реНрдЪ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ред

рд▓реЛрдбрд░


рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдмреВрдЯ рд▓реЛрдбрд░ рдХреА рд╕рдореАрдХреНрд╖рд╛ рдХреА рдЬрд╛рдПрдЧреАред рд▓реЛрдбрд░ рдореЗрдВ рдХреЛрдИ рдирд┐рд░реНрднрд░рддрд╛ рдирд╣реАрдВ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП, рдЗрд╕рд▓рд┐рдП рдорд╛рдирдХ рд╕реА рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╕реЗ рд╕рднреА рдЖрд╡рд╢реНрдпрдХ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд╕реНрд╡рддрдВрддреНрд░ рд░реВрдк рд╕реЗ рд▓рд┐рдЦрдирд╛ рд╣реЛрдЧрд╛ (рдЗрди рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╕рдВрджрд░реНрдн рджреНрд╡рд╛рд░рд╛ рдЙрдкрд▓рдмреНрдз рд╣реИ)ред рдпрд╣ рднреА рд╕реНрдерд┐рддрд┐ рд╕реНрд╡рддрдВрддреНрд░ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред

_Start рдлрд╝рдВрдХреНрд╢рди


рдмреВрдЯрд▓реЛрдбрд░ _start рдлрд╝рдВрдХреНрд╢рди рд╕реЗ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ, рдЬреЛ рдмрд╕ argc рдФрд░ argv рд╕реЗ рдЧреБрдЬрд░рддрд╛ рд╣реИ:

 .extern main .globl _start .text _start: movq (%rsp), %rdi movq %rsp, %rsi addq $8, %rsi call main 

рдореБрдЦреНрдп рд╕рдорд╛рд░реЛрд╣


Main.c рдлрд╝рд╛рдЗрд▓ рдХрдИ рдмрд╛рд╣рд░реА рдЪрд░ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рд╕реЗ рд╢реБрд░реВ рд╣реЛрддреА рд╣реИ:

 extern void* loader_end; //    , .   //  ELF . extern size_t payload_size; //   ELF  extern size_t key_seed; //     // -   . extern size_t iv_seed; //     // -     

рдкреИрдХрд░ рдореЗрдВ рдЪрд░ (Elf64_Sym) рдХреЗ рдЕрдиреБрд░реВрдк рд╡рд░реНрдгреЛрдВ рдХреА рд╕реНрдерд┐рддрд┐ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдФрд░ рдЙрдирдХреЗ рдореВрд▓реНрдпреЛрдВ рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдирдореЗрдВ рд╕реЗ рд╕рднреА рдХреЛ рдмрд╛рд╣рд░реА рдШреЛрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдореБрдЦреНрдп рдХрд╛рд░реНрдп рдЕрдкрдиреЗ рдЖрдк рдореЗрдВ рдХрд╛рдлреА рд╕рд░рд▓ рд╣реИред рдкрд╣рд▓рд╛ рдХрджрдо рдПрдХ рднрд░реЗ рд╣реБрдП рдИрдПрд▓рдПрдл рдлрд╝рд╛рдЗрд▓, рдПрдХ 256-рдмрд╛рдЗрдЯ рдмрдлрд░, рдФрд░ рд╕реНрдЯреИрдХ рдХреЗ рд╢реАрд░реНрд╖ рдкрд░ рдЗрдВрдЧрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИред рдлрд┐рд░ рдИрдПрд▓рдПрдл рдлрд╝рд╛рдЗрд▓ рдХреЛ рдбрд┐рдХреНрд░рд┐рдкреНрдЯ рдФрд░ рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдлрд┐рд░ рдЗрд╕реЗ рд▓реЛрдб_рдлреНрд▓реЛ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдореЗрдореЛрд░реА рдореЗрдВ рд╕рд╣реА рд╕реНрдерд╛рди рдкрд░ рд░рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдЕрдВрдд рдореЗрдВ, рдЖрд░рдПрд╕рдкреА рд░рдЬрд┐рд╕реНрдЯрд░ рдХрд╛ рдореВрд▓реНрдп рдЗрд╕рдХреА рдореВрд▓ рд╕реНрдерд┐рддрд┐ рдореЗрдВ рд▓реМрдЯрддрд╛ рд╣реИ, рдФрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдПрдВрдЯреНрд░реА рдкреЙрдЗрдВрдЯ рдкрд░ рдПрдХ рдХреВрдж рд╣реЛрддрд╛ рд╣реИ:

 #define SET_STACK(sp) __asm__ __volatile__ ("movq %0, %%rsp"::"r"(sp)) #define JMP(addr) __asm__ __volatile__ ("jmp *%0"::"r"(addr)) int main(int argc, char **argv) { uint8_t *payload = (uint8_t*)&loader_end; //    // ELF  uint8_t *entropy_buf = payload + payload_size; //   256- //  void *rsp = argv-1; //     struct AES_ctx ctx; AES_init_ctx_iv(&ctx, entropy_buf, key_seed, iv_seed); //  AES AES_CTR_xcrypt_buffer(&ctx, payload, payload_size); //  ELF memset(&ctx, 0, sizeof(ctx)); //   AES size_t decoded_payload_size; //  ELF char *decoded_payload = huffman_decode((char*)payload, payload_size, &decoded_payload_size); //     ELF  , //   ET_EXEC  NULL. void *load_addr = elf_load_addr(rsp, decoded_payload, decoded_payload_size); load_addr = load_elf(load_addr, decoded_payload); //  ELF  , //    //  . memset(decoded_payload, 0, decoded_payload_size); //   ELF munmap(decoded_payload, decoded_payload_size); //   //    //  ELF     AES AES_init_ctx_iv(&ctx, entropy_buf, key_seed, iv_seed); AES_CTR_xcrypt_buffer(&ctx, payload, payload_size); memset(&ctx, 0, sizeof(ctx)); SET_STACK(rsp); //    JMP(load_addr); //       } 

рдПрдИрдПрд╕ рдФрд░ рд╡рд┐рдШрдЯрд┐рдд рдИрдПрд▓рдПрдл рдлрд╝рд╛рдЗрд▓ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рд░реАрд╕реЗрдЯ рдХрд░рдирд╛ рд╕реБрд░рдХреНрд╖рд╛ рдЙрджреНрджреЗрд╢реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ - рддрд╛рдХрд┐ рдХреБрдВрдЬреА рдФрд░ рдбрд┐рдХреНрд░рд┐рдкреНрдЯ рдХрд┐рдП рдЧрдП рдбреЗрдЯрд╛ рдХреЛ рдХреЗрд╡рд▓ рдЙрдкрдпреЛрдЧ рдХреЗ рд╕рдордп рдХреЗ рд▓рд┐рдП рдореЗрдореЛрд░реА рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рдПред

рдЖрдЧреЗ рдХреБрдЫ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

load_elf


рдореИрдВрдиреЗ рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдЕрдкрдиреЗ рдпреВрдЬрд░рд▓реИрдВрдбрдПрдХреНрд╕ec рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рд╕реЗ рдЙрдкрдирд╛рдо рдмреЗрдбрд┐рдЧрд░ рдХреЗ рд╕рд╛рде рдЬреАрдердм рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реЗ рд▓рд┐рдпрд╛ рдФрд░ рдЗрд╕реЗ рдЕрдВрддрд┐рдо рд░реВрдк рджрд┐рдпрд╛, рдХреНрдпреЛрдВрдХрд┐ рдореВрд▓ рдлрд╝рдВрдХреНрд╢рди ET_DYN рдЬреИрд╕реА рдлрд╝рд╛рдЗрд▓реЛрдВ рдкрд░ рдХреНрд░реИрд╢ рд╣реЛ рдЧрдпрд╛ред рд╡рд┐рдлрд▓рддрд╛ рдЗрд╕ рддрдереНрдп рдХреЗ рдХрд╛рд░рдг рд╣реБрдИ рдХрд┐ рдПрдордПрдордПрдкреА рдкреНрд░рдгрд╛рд▓реА рдХреЙрд▓ рдХреЗ рдкрд╣рд▓реЗ рддрд░реНрдХ рдХрд╛ рдореВрд▓реНрдп NULL рдкрд░ рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдФрд░ рдкрддрд╛ рдореБрдЦреНрдп рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЗ рдХрд╛рдлреА рдХрд░реАрдм рд▓реМрдЯ рдЖрдпрд╛ рдерд╛, рдмрд╛рдж рдореЗрдВ рдореИрдордк рдХреЛ рдХреЙрд▓ рдФрд░ рдЙрдирдХреЗ рджреНрд╡рд╛рд░рд╛ рджрд┐рдП рдЧрдП рдкрддреЗ рдкрд░ рд╕реЗрдЧрдореЗрдВрдЯ рдХреЙрдкреА рдХрд░рдиреЗ рдХреЗ рджреМрд░рд╛рди, рдореБрдЦреНрдп рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХрд╛ рдХреЛрдб рдУрд╡рд░рд░рд╛рдЗрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдФрд░ рд╕реЗрдЧрдлреЙрд▓реНрдЯ рд╣реБрдЖред рдЗрд╕рд▓рд┐рдП, рд▓реЛрдбрд┐рдВрдЧ / рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рд╢реБрд░реБрдЖрддреА рдкрддреЗ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдлрд╝рдВрдХреНрд╢рди рд╕реНрд╡рдпрдВ рд╕рднреА рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╣реЗрдбрд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЬрд╛рддрд╛ рд╣реИ, рдПрд▓рдИрдПрдл рдлрд╝рд╛рдЗрд▓ рдХреЗ PT_LOAD рд╕реЗрдЧрдореЗрдВрдЯ рдХреЗ рд▓рд┐рдП рдореЗрдореЛрд░реА рдЖрд╡рдВрдЯрд┐рдд рдХрд░рддрд╛ рд╣реИ (рдЗрд╕рдХреА рд╕рдВрдЦреНрдпрд╛ рдкреГрд╖реНрда рдЖрдХрд╛рд░ рдХрд╛ рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП), рдЖрд╡рдВрдЯрд┐рдд рдореЗрдореЛрд░реА рдХреНрд╖реЗрддреНрд░реЛрдВ рдореЗрдВ рдЙрдирдХреА рд╕рд╛рдордЧреНрд░реА рдХреА рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдмрдирд╛рддрд╛ рд╣реИ рдФрд░ рдЗрди рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рд▓рд┐рдП рдЗрд╕реА рдкрдврд╝рдиреЗ, рд▓рд┐рдЦрдиреЗ, рдирд┐рд╖реНрдкрд╛рджрди рдЕрдзрд┐рдХрд╛рд░ рд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИ:

 //      #define PAGEUP(x) (((unsigned long)x + 4095)&(~4095)) //      #define PAGEDOWN(x) ((unsigned long)x&(~4095)) void* load_elf(void *load_addr, void *mapped) { Elf64_Ehdr *ehdr = mapped; Elf64_Phdr *phdr = mapped + ehdr->e_phoff; void *text_segment = NULL; unsigned long initial_vaddr = 0; unsigned long brk_addr = 0; for(size_t i = 0; i < ehdr->e_phnum; i++, phdr++) { unsigned long rounded_len, k; void *segment; //   PT_LOAD,    if(phdr->p_type != PT_LOAD) continue; if(text_segment != 0 && ehdr->e_type == ET_DYN) { //  ET_DYN phdr->p_vaddr    , //        //    ,      //     load_addr = text_segment + phdr->p_vaddr - initial_vaddr; load_addr = (void*)PAGEDOWN(load_addr); } else if(ehdr->e_type == ET_EXEC) { //  ET_EXEC phdr->p_vaddr     load_addr = (void*)PAGEDOWN(phdr->p_vaddr); } //        rounded_len = phdr->p_memsz + (phdr->p_vaddr % 4096); rounded_len = PAGEUP(rounded_len); //        segment = mmap(load_addr, rounded_len, PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0); if(ehdr->e_type == ET_EXEC) load_addr = (void*)phdr->p_vaddr; else load_addr = segment + (phdr->p_vaddr % 4096); //         memcpy(load_addr, mapped + phdr->p_offset, phdr->p_filesz); if(!text_segment) { text_segment = segment; initial_vaddr = phdr->p_vaddr; } unsigned int protflags = 0; if(phdr->p_flags & PF_R) protflags |= PROT_READ; if(phdr->p_flags & PF_W) protflags |= PROT_WRITE; if(phdr->p_flags & PF_X) protflags |= PROT_EXEC; mprotect(segment, rounded_len, protflags); //   // , ,  k = phdr->p_vaddr + phdr->p_memsz; if(k > brk_addr) brk_addr = k; } if (ehdr->e_type == ET_EXEC) { brk(PAGEUP(brk_addr)); //  ET_EXEC ehdr->e_entry     load_addr = (void*)ehdr->e_entry; } else { //  ET_DYN ehdr->e_entry    , //           load_addr = (void*)ehdr + ehdr->e_entry; } return load_addr; //       } 

elf_load_addr


ET_EXEC ELF рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд▓рд┐рдП рдпрд╣ рдлрд╝рдВрдХреНрд╢рди NULL рд▓реМрдЯрд╛рддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреА рдлрд╛рдЗрд▓реЗрдВ рдЙрдирдореЗрдВ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдкрддреЗ рдкрд░ рд╕реНрдерд┐рдд рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдПред ET_DYN рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд▓рд┐рдП, рдореБрдЦреНрдп рдХрд╛рд░реНрдпрдХреНрд░рдо (рдпрд╛рдиреА, рдмреВрдЯрд▓реЛрдбрд░) рдХреЗ рдЖрдзрд╛рд░ рдкрддреЗ рдХреЗ рдмреАрдЪ рдЕрдВрддрд░ рдХреЗ рдмрд░рд╛рдмрд░ рдкрддрд╛, рдореЗрдореЛрд░реА рдореЗрдВ ELF рдХреЛ рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдореЗрдореЛрд░реА рдХреА рдорд╛рддреНрд░рд╛, рдФрд░ 4096, 4096 - рдЕрдВрддрд░рд╛рд▓ рддрд╛рдХрд┐ рдореБрдЦреНрдп рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЗ рдареАрдХ рдмрдЧрд▓ рдореЗрдВ ELF рдлрд╝рд╛рдЗрд▓ рдХреЛ рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдкрд╣рд▓реЗ рдЧрдгрдирд╛ рдирд╣реАрдВ рдХреА рдЬрд╛рддреА рд╣реИред рдЗрд╕ рдкрддреЗ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдпрд╣ рдЬрд╛рдВрдЪрд╛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдореЗрдореЛрд░реА рдХреНрд╖реЗрддреНрд░ рдЕрдВрддрд░рд┐рдд рд╣реИ, рджрд┐рдП рдЧрдП рдкрддреЗ рд╕реЗ рдореБрдЦреНрдп рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЗ рдЖрдзрд╛рд░ рдкрддреЗ рддрдХ, рдЕрдирдкреИрдХреНрдб рдИрдПрд▓рдПрдл рдлрд╝рд╛рдЗрд▓ рдХреА рд╢реБрд░реБрдЖрдд рд╕реЗ рдЗрд╕рдХреЗ рдЕрдВрдд рддрдХ рдХрд╛ рдХреНрд╖реЗрддреНрд░ред рдЪреМрд░рд╛рд╣реЗ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдкрддреЗ рдХреЛ рдЕрдирдкреИрдХ рдХрд┐рдП рдЧрдП рдИрдПрд▓рдПрдл рдХреЗ рдкреНрд░рд╛рд░рдВрдн рдкрддреЗ рдФрд░ рдЗрд╕реЗ рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдореЗрдореЛрд░реА рдХреА рдорд╛рддреНрд░рд╛ рдХреЗ рдмреАрдЪ рдЕрдВрддрд░ рдХреЗ рдмрд░рд╛рдмрд░ рд▓реМрдЯрд╛ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЕрдиреНрдпрдерд╛ рдкрд╣рд▓реЗ рд╕реЗ рдЧрдгрдирд╛ рдХрд┐рдП рдЧрдП рдкрддреЗ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХрд╛ рдЖрдзрд╛рд░ рдкрддрд╛ рд╕рд╣рд╛рдпрдХ рд╡реЗрдХреНрдЯрд░ (ELF рд╕рд╣рд╛рдпрдХ рд╡реЗрдХреНрдЯрд░) рд╕реЗ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╣реЗрдбрд░ рдХрд╛ рдкрддрд╛ рдирд┐рдХрд╛рд▓рдХрд░ рдкрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рд╕реНрдЯреИрдХ рдореЗрдВ рдкрд░реНрдпрд╛рд╡рд░рдг рдЪрд░ рдХреЗ рд╕рдВрдХреЗрдд рдХреЗ рдмрд╛рдж рд╕реНрдерд┐рдд рд╣реИ, рдФрд░ рдЗрд╕рдХреЗ рд╕рд╛рде ELF рд╣реЗрдбрд░ рдХреЗ рдЖрдХрд╛рд░ рдХреЛ рдШрдЯрд╛рдХрд░:

       ---------------------------------------------------------------------------    -> [ argc ] 8 [ argv[0] ] 8 [ argv[1] ] 8 [ argv[..] ] 8 * x [ argv[n тАУ 1] ] 8 [ argv[n] ] 8 (= NULL) [ envp[0] ] 8 [ envp[1] ] 8 [ envp[..] ] 8 [ envp[term] ] 8 (= NULL) [ auxv[0] (Elf64_auxv_t) ] 16 [ auxv[1] (Elf64_auxv_t) ] 16 [ auxv[..] (Elf64_auxv_t) ] 16 [ auxv[term] (Elf64_auxv_t) ] 16 (= AT_NULL) [  ] 0 - 16 [    ] >= 0 [   ] >= 0 [   ] 8 (= NULL) <    > 0 --------------------------------------------------------------------------- 

рд╡рд╣ рд╕рдВрд░рдЪрдирд╛ рдЬрд┐рд╕рдХреЗ рджреНрд╡рд╛рд░рд╛ рд╕рд╣рд╛рдпрдХ рд╡реЗрдХреНрдЯрд░ рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рддрддреНрд╡ рдХрд╛ рд╡рд░реНрдгрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:

 typedef struct { uint64_t a_type; //   union { uint64_t a_val; //  } a_un; } Elf64_auxv_t; 

рдорд╛рдиреНрдп a_type рдорд╛рдиреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ AT_PHDR рд╣реИ, a_val рддрдм рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╣реЗрдбрд░ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░реЗрдЧрд╛ред рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд elf_load_addr рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдХреЛрдб рд╣реИ:

 void* elf_base_addr(void *rsp) { void *base_addr = NULL; unsigned long argc = *(unsigned long*)rsp; char **envp = rsp + (argc+2)*sizeof(unsigned long); //    //   while(*envp++); //        Elf64_auxv_t *aux = (Elf64_auxv_t*)envp; //    //  for(; aux->a_type != AT_NULL; aux++) { //        if(aux->a_type == AT_PHDR) { //   ELF ,     //      base_addr = (void*)(aux->a_un.a_val тАУ sizeof(Elf64_Ehdr)); break; } } return base_addr; } size_t elf_memory_size(void *mapped) { Elf64_Ehdr *ehdr = mapped; Elf64_Phdr *phdr = mapped + ehdr->e_phoff; size_t mem_size = 0, segment_len; for(size_t i = 0; i < ehdr->e_phnum; i++, phdr++) { if(phdr->p_type != PT_LOAD) continue; segment_len = phdr->p_memsz + (phdr->p_vaddr % 4096); mem_size += PAGEUP(segment_len); } return mem_size; } void* elf_load_addr(void *rsp, void *mapped, size_t mapped_size) { Elf64_Ehdr *ehdr = mapped; if(ehdr->e_type == ET_EXEC) return NULL; size_t mem_size = elf_memory_size(mapped) + 0x1000; void *load_addr = elf_base_addr(rsp); if(mapped < load_addr && mapped + mapped_size > load_addr - mem_size) load_addr = mapped; return load_addr - mem_size; } 

рд▓рд┐рдВрдХрд░ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╡рд┐рд╡рд░рдг


рдЙрдкрд░реЛрдХреНрдд рд╡рд░реНрдгрд┐рдд рдмрд╛рд╣рд░реА рдЪрд░ рдХреЗ рд▓рд┐рдП рд╡рд░реНрдгреЛрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ, рдФрд░ рдпрд╣ рднреА рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ рдХрд┐ рд╕рдВрдХрд▓рди рдХреЗ рдмрд╛рдж рдХреЛрдб рдФрд░ рд▓реЛрдбрд░ рдбреЗрдЯрд╛ рдПрдХ рд╣реА .text рдЕрдиреБрднрд╛рдЧ рдореЗрдВ рд╣реИрдВред рдлрд╝рд╛рдЗрд▓ рд╕реЗ рдЗрд╕ рдЕрдиреБрднрд╛рдЧ рдХреА рд╕рд╛рдордЧреНрд░реА рдХреЛ рдХрд╛рдЯрдХрд░ рд▓реЛрдбрд░ рдорд╢реАрди рдХреЛрдб рдХреЛ рдЖрд╕рд╛рдиреА рд╕реЗ рдирд┐рдХрд╛рд▓рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдЗрди рд▓рдХреНрд╖реНрдпреЛрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд▓рд┐рдВрдХрд░ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд▓рд┐рдЦреА рдЧрдИ рдереА:

 ENTRY(_start) SECTIONS { . = 0; .text :{ *(.text) *(.text.startup) *(.data) *(.rodata) payload_size = .; QUAD(0) key_seed = .; QUAD(0) iv_seed = .; QUAD(0) loader_end = .; } } 

рдпрд╣ рд╕рдордЭрд╛рдиреЗ рдпреЛрдЧреНрдп рд╣реИ рдХрд┐ QUAD (0) рд╢реВрдиреНрдп рдХреЗ 8 рдмрд╛рдЗрдЯреНрд╕ рд░рдЦрддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рдмрдЬрд╛рдп рдкреИрдХрд░ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдореВрд▓реНрдпреЛрдВ рдХреЛ рд╕реНрдерд╛рдирд╛рдкрдиреНрди рдХрд░реЗрдЧрд╛ред рдорд╢реАрди рдХреЛрдб рдХреЛ рдХрд╛рдЯрдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХ рдЫреЛрдЯреА рд╕реА рдЙрдкрдпреЛрдЧрд┐рддрд╛ рд▓рд┐рдЦреА рдЧрдИ рдереА, рдЬреЛ рдорд╢реАрди рдХреЛрдб рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдмреВрдЯрд▓реЛрдбрд░ рдХреА рд╢реБрд░реБрдЖрдд рд╕реЗ рдмреВрдЯрд▓реЛрдбрд░ рдореЗрдВ рдкреНрд░рд╡реЗрд╢ рдмрд┐рдВрджреБ рдХреА рд╢рд┐рдлреНрдЯ рдХреЛ рд▓рд┐рдЦрддрд╛ рд╣реИ, рдмреВрдЯ рд▓реЛрдбрд░ рдХреА рд╢реБрд░реБрдЖрдд рд╕реЗ рдкреЗрд▓реЛрдб_рд╕рд╛рдЗрдЬ, рдХреА_рдПрдбреЗрдб рдФрд░ iv_seed рдЕрдХреНрд╖рд░реЛрдВ рдХреЗ рдореВрд▓реНрдпреЛрдВ рдХреА рднрд░рдкрд╛рдИ рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рдЙрдкрдпреЛрдЧрд┐рддрд╛ рдХрд╛ рдХреЛрдб рдпрд╣рд╛рдБ рдЙрдкрд▓рдмреНрдз рд╣реИ ред рдпрд╣ рдмреВрдЯрд▓реЛрдбрд░ рд╡рд┐рд╡рд░рдг рдХреЛ рд╕рдорд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИред

рд╕реАрдзреЗ рдкреИрдХрд░


рдкреИрдХрд░ рдХреЗ рдореБрдЦреНрдп рдХрд╛рд░реНрдп рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред рдпрд╣ рджреЛ рдХрдорд╛рдВрдб рд▓рд╛рдЗрди рддрд░реНрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ: рдЗрдирдкреБрдЯ рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдирд╛рдо argv [1] рд╣реИ рдФрд░ рдЖрдЙрдЯрдкреБрдЯ рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдирд╛рдо argv [2] рд╣реИред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЗрдирдкреБрдЯ рдлрд╝рд╛рдЗрд▓ рдХреЛ рдореЗрдореЛрд░реА рдореЗрдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдкреИрдХрд░ рдХреЗ рд╕рд╛рде рд╕рдВрдЧрддрддрд╛ рдХреЗ рд▓рд┐рдП рдЬрд╛рдБрдЪ рдХреА рдЬрд╛рддреА рд╣реИред рдкреИрдХрд░ рдХреЗрд╡рд▓ рджреЛ рдкреНрд░рдХрд╛рд░ рдХреА рдИрдПрд▓рдПрдл рдлрд╛рдЗрд▓реЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ: ET_EXEC рдФрд░ ET_DYN, рдФрд░ рдХреЗрд╡рд▓ рд╕рд╛рдВрдЦреНрдпрд┐рдХреАрдп рд░реВрдк рд╕реЗ рд╕рдВрдХрд▓рд┐рдд рд▓реЛрдЧреЛрдВ рдХреЗ рд╕рд╛рдеред рдЗрд╕ рдкреНрд░рддрд┐рдмрдВрдз рдХреЛ рд╢реБрд░реВ рдХрд░рдиреЗ рдХрд╛ рдХрд╛рд░рдг рдпрд╣ рдерд╛ рдХрд┐ рд╡рд┐рднрд┐рдиреНрди рд▓рд┐рдирдХреНрд╕ рдкреНрд░рдгрд╛рд▓рд┐рдпреЛрдВ рдореЗрдВ рд╕рд╛рдЭрд╛ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреЗ рд╡рд┐рднрд┐рдиреНрди рд╕рдВрд╕реНрдХрд░рдг рд╣реИрдВ, рдЕрд░реНрдерд╛рддред рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИ рдХрд┐ рдПрдХ рдЧрддрд┐рд╢реАрд▓ рд╕рдВрдХрд▓рд┐рдд рдХрд╛рд░реНрдпрдХреНрд░рдо рдореВрд▓ рд╕рд┐рд╕реНрдЯрдо рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдХрд┐рд╕реА рдЕрдиреНрдп рд╕рд┐рд╕реНрдЯрдо рдкрд░ рд╢реБрд░реВ рдирд╣реАрдВ рд╣реЛрдЧрд╛ред рдореБрдЦреНрдп рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рд╕рдВрдмрдВрдзрд┐рдд рдХреЛрдб:

 size_t mapped_size; void *mapped = map_file(argv[1], &mapped_size); if(check_elf(mapped) < 0) return 1; 

рдЙрд╕рдХреЗ рдмрд╛рдж, рдпрджрд┐ рдЗрдирдкреБрдЯ рдлрд╝рд╛рдЗрд▓ рд╕рдВрдЧрддрддрд╛ рдЬрд╛рдВрдЪ рд╕реЗ рдЧреБрдЬрд░рддреА рд╣реИ, рддреЛ рдпрд╣ рд╕рдВрдкреАрдбрд╝рд┐рдд рд╣реИ:

 size_t comp_size; uint8_t *comp_buf = huffman_encode(mapped, &comp_size); 

рдЕрдЧрд▓рд╛, рдПрдИрдПрд╕ рд╕реНрдерд┐рддрд┐ рдЙрддреНрдкрдиреНрди рд╣реЛрддреА рд╣реИ, рдФрд░ рд╕рдВрдХреБрдЪрд┐рдд рдИрдПрд▓рдПрдл рдлрд╝рд╛рдЗрд▓ рдПрдиреНрдХреНрд░рд┐рдкреНрдЯ рдХреА рдЬрд╛рддреА рд╣реИред рдПрдИрдПрд╕ рдХреА рд╕реНрдерд┐рддрд┐ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рдВрд░рдЪрдирд╛ рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХреА рдЬрд╛рддреА рд╣реИ:

 #define AES_ENTROPY_BUFSIZE 256 typedef struct { uint8_t entropy_buf[AES_ENTROPY_BUFSIZE]; // 256-  size_t key_seed; //      size_t iv_seed; //       struct AES_ctx ctx; //  AES-CTR } AES_state_t; 

рдореБрдЦреНрдп рдореЗрдВ рдХреЛрдбрд┐рдВрдЧ:

 AES_state_t aes_st; for(int i = 0; i < AES_ENTROPY_BUFSIZE; i++) state.entropy_buf[i] = rand() % 256; state.key_seed = rand(); state.iv_seed = rand(); AES_init_ctx_iv(&state.ctx, state.entropy_buf, state.key_seed, state.iv_seed); AES_CTR_xcrypt_buffer(&aes_st.ctx, comp_buf, comp_size); 

рдЙрд╕рдХреЗ рдмрд╛рдж, рдмреВрдЯрд▓реЛрдбрд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рд╡рд╛рд▓реА рд╕рдВрд░рдЪрдирд╛ рдХреЛ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдмреВрдЯрд▓реЛрдбрд░ рдореЗрдВ рдкреЗрд▓реЛрдб_рд╕рд╛рдЗрдЬрд╝, рдХреА_рд╕реЗрдб рдФрд░ iv_seed рд╡реИрд▓реНрдпреВ рдХреЛ рдкрд┐рдЫрд▓реЗ рдЪрд░рдг рдореЗрдВ рдЙрддреНрдкрдиреНрди рдЙрди рд▓реЛрдЧреЛрдВ рдореЗрдВ рдмрджрд▓ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рдмрд╛рдж рдПрдИрдПрд╕ рд╕реНрдЯреЗрдЯ рд░реАрд╕реЗрдЯ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред рдмреВрдЯрд▓реЛрдбрд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реИ:

 typedef struct { char *loader_begin; //      size_t entry_offset; //       size_t *payload_size_patch_offset; //     // ELF    size_t *key_seed_pacth_offset; //     //       size_t *iv_seed_patch_offset; //     //     //    size_t loader_size; //     } loader_t; 

рдореБрдЦреНрдп рдореЗрдВ рдХреЛрдбрд┐рдВрдЧ:

 loader_t loader; init_loader(&loader); *loader.payload_size_patch_offset = comp_size; *loader.key_seed_pacth_offset = aes_st.key_seed; *loader.iv_seed_patch_offset = aes_st.iv_seed; memset(&aes_st.ctx, 0, sizeof(aes_st.ctx)); 

рдЕрдВрддрд┐рдо рднрд╛рдЧ рдореЗрдВ, рд╣рдо рдПрдХ рдЖрдЙрдЯрдкреБрдЯ рдлрд╛рдЗрд▓ рдмрдирд╛рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдореЗрдВ рдПрдХ рдИрдПрд▓рдПрдл рд╣реЗрдбрд░, рдПрдХ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╣реЗрдбрд░, рдПрдХ рд▓реЛрдбрд░ рдХреЛрдб, рдПрдХ рд╕рдВрдкреАрдбрд╝рд┐рдд рдФрд░ рдПрдиреНрдХреНрд░рд┐рдкреНрдЯреЗрдб рдИрдПрд▓рдПрдл рдлрд╛рдЗрд▓ рдФрд░ рдПрдХ 256 рдмрд╛рдЗрдЯ рдмрдлрд░ рд▓рд┐рдЦрддреЗ рд╣реИрдВ:

 int out_fd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0755); //  //   write_elf_ehdr(out_fd, &loader); //  ELF  write_elf_phdr(out_fd, &loader, comp_size); //    write(out_fd, loader.loader_begin, loader.loader_size); //   write(out_fd, comp_buf, comp_size); //     ELF write(out_fd, aes_st.entropy_buf, AES_ENTROPY_BUFSIZE); //  // 256-  

рдкреИрдХрд░ рдХрд╛ рдореБрдЦреНрдп рдХреЛрдб рдпрд╣рд╛рдВ рд╕рдорд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИ, рдлрд┐рд░ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрд╛рд░реНрдпреЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛: рдмреВрдЯрд▓реЛрдбрд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдХрд╛ рдХрд╛рд░реНрдп, рдИрдПрд▓рдПрдл рд╣реЗрдбрд░ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдХрд╛рд░реНрдп рдФрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╣реЗрдбрд░ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдХрд╛рд░реНрдпред

рдЖрд░рдВрднрд┐рдХ рдмреВрдЯрд▓реЛрдбрд░ рдЬрд╛рдирдХрд╛рд░реА


рд▓реЛрдбрд░ рдорд╢реАрди рдХреЛрдб рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рд╕рд░рд▓ рдХреЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреИрдХрд░ рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдореЗрдВ рдПрдореНрдмреЗрдбреЗрдб рд╣реИ:

 .data .globl _loader_begin .globl _loader_end _loader_begin: .incbin "loader" _loader_end: 

рд╕реНрдореГрддрд┐ рдореЗрдВ рдЗрд╕рдХрд╛ рдкрддрд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореБрдЦреНрдп рдЪрд░ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЪрд░ рдШреЛрд╖рд┐рдд рдХрд┐рдП рдЧрдП рд╣реИрдВ:

 extern void* _loader_begin; extern void* _loader_end; 

рдЕрдЧрд▓рд╛, init_loader рдлрд╝рдВрдХреНрд╢рди рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдорд╛рдиреЛрдВ рдХреЛ рдХреНрд░рдорд┐рдХ рд░реВрдк рд╕реЗ рдЗрд╕рдореЗрдВ рдкрдврд╝рд╛ рдЬрд╛рддрд╛ рд╣реИ: рдмреВрдЯрд▓реЛрдбрд░ (рдПрдВрдЯреНрд░реА_рдСрдлрд╕реЗрдЯ) рдХреА рд╢реБрд░реБрдЖрдд рд╕реЗ рдкреНрд░рд╡реЗрд╢ рдмрд┐рдВрджреБ рдХреА рднрд░рдкрд╛рдИ, рдмреВрдЯрд▓реЛрдбрд░ (рдкреЗрд▓реЛрдбред Size_patch_offset) рдХреА рд╢реБрд░реБрдЖрдд рд╕реЗ рд▓реЛрдб рдХрд┐рдП рдЧрдП ELF рдлрд╝рд╛рдЗрд▓ рдХреЗ рдЖрдХрд╛рд░ рдХреА рдкрд╛рд░реА, рдмреВрдЯрд▓реЛрдбрд░ рдХреА рд╢реБрд░реБрдЖрдд рд╕реЗ рдХреБрдВрдЬреА рдХреЗ рд▓рд┐рдП рдЬрдирд░реЗрдЯрд░ рдХреЗ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдореВрд▓реНрдп рдХреА рдкрд╛рд░реАред рдмреВрдЯрд▓реЛрдбрд░ (iv_seed_patch_offset) рдХреА рд╢реБрд░реБрдЖрдд рд╕реЗред рдлрд┐рд░, рд▓реЛрдбрд░ рдкрддреЗ рдХреЛ рдЕрдВрддрд┐рдо рддреАрди рдорд╛рдиреЛрдВ рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЬрдм рдмрд┐рдВрджреБрдУрдВ рдХреЛ рд╕рдВрджрд░реНрднрд┐рдд рдХрд░рддреЗ рд╣реБрдП рдФрд░ рдЙрдиреНрд╣реЗрдВ рдорд╛рди рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдЙрди рд▓реЗрдЖрдЙрдЯ рдЪрд░рдгреЛрдВ (QUAD (0)) рдореЗрдВ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рд╢реВрдиреНрдп рдХреЛ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВрдЧреЗ рдЬрд┐рдирдХреА рд╣рдореЗрдВ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

 void init_loader(loader_t *l) { void *loader_begin = (void*)&_loader_begin; l->entry_offset = *(size_t*)loader_begin; loader_begin += sizeof(size_t); l->payload_size_patch_offset = *(void**)loader_begin; loader_begin += sizeof(void*); l->key_seed_pacth_offset = *(void**)loader_begin; loader_begin += sizeof(void*); l->iv_seed_patch_offset = *(void**)loader_begin; loader_begin += sizeof(void*); l->payload_size_patch_offset = (size_t)l->payload_size_patch_offset + loader_begin; l->key_seed_pacth_offset = (size_t)l->key_seed_pacth_offset + loader_begin; l->iv_seed_patch_offset = (size_t)l->iv_seed_patch_offset + loader_begin; l->loader_begin = loader_begin; l->loader_size = (void*)&_loader_end - loader_begin; } 


write_elf_ehdr


 void write_elf_ehdr(int fd, loader_t *loader) { //  ELF  Elf64_Ehdr ehdr; memset(ehdr.e_ident, 0, sizeof(ehdr.e_ident)); memcpy(ehdr.e_ident, ELFMAG, SELFMAG); ehdr.e_ident[EI_CLASS] = ELFCLASS64; ehdr.e_ident[EI_DATA] = ELFDATA2LSB; ehdr.e_ident[EI_VERSION] = EV_CURRENT; ehdr.e_ident[EI_OSABI] = ELFOSABI_NONE; ehdr.e_type = ET_DYN; ehdr.e_machine = EM_X86_64; ehdr.e_version = EV_CURRENT; ehdr.e_entry = sizeof(Elf64_Ehdr) + sizeof(Elf64_Phdr) + loader->entry_offset; ehdr.e_phoff = sizeof(Elf64_Ehdr); ehdr.e_shoff = 0; ehdr.e_flags = 0; ehdr.e_ehsize = sizeof(Elf64_Ehdr); ehdr.e_phentsize = sizeof(Elf64_Phdr); ehdr.e_phnum = 1; ehdr.e_shentsize = sizeof(Elf64_Shdr); ehdr.e_shnum = 0; ehdr.e_shstrndx = 0; write(fd, &ehdr, sizeof(ehdr)); //     return 0; } 

рдпрд╣рд╛рдВ рдИрдПрд▓рдПрдл рд╣реЗрдбрд░ рдХрд╛ рдорд╛рдирдХ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝реЗрд╢рди рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдПрдХ рдлрд╝рд╛рдЗрд▓ рдХреЗ рд▓рд┐рдП рдЙрд╕рдХреЗ рдмрд╛рдж рдХреЗ рд▓реЗрдЦрди рдореЗрдВ, рдХреЗрд╡рд▓ рдПрдХ рдЪреАрдЬ рдЬреЛ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИ рд╡рд╣ рдпрд╣ рд╣реИ рдХрд┐ ET_DYN ELF рдлрд╝рд╛рдЗрд▓реЛрдВ рдореЗрдВ рдкрд╣рд▓реЗ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╣реЗрдбрд░ рджреНрд╡рд╛рд░рд╛ рд╡рд░реНрдгрд┐рдд рд╕реЗрдЧрдореЗрдВрдЯ рдореЗрдВ рди рдХреЗрд╡рд▓ рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдХреЛрдб, рдмрд▓реНрдХрд┐ рдИрдПрд▓рдПрдл рд╣реЗрдбрд░ рдФрд░ рд╕рднреА рд╣реЗрдбрд░ рднреА рд╢рд╛рдорд┐рд▓ рд╣реИрдВред рдХрд╛рд░реНрдпрдХреНрд░рдоред рдЗрд╕рд▓рд┐рдП, рдЗрд╕рдХреА рд╢реБрд░реБрдЖрдд рд╕реЗ рдСрдлрд╕реЗрдЯ рд╢реВрдиреНрдп рдХреЗ рдмрд░рд╛рдмрд░ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдЖрдХрд╛рд░ рдИрдПрд▓рдПрдл рд╣реЗрдбрд░, рд╕рднреА рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╣реЗрдбрд░ рдФрд░ рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдХреЛрдб рдХреЗ рдЖрдХрд╛рд░ рдХрд╛ рдпреЛрдЧ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдФрд░ рдкреНрд░рд╡реЗрд╢ рдмрд┐рдВрджреБ рдИрдПрд▓рдПрдл рд╣реЗрдбрд░ рдХреЗ рдЖрдХрд╛рд░ рдХреЗ рдпреЛрдЧ рдХреЗ рд░реВрдк рдореЗрдВ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд╕рднреА рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╣реЗрдбрд░ рдХрд╛ рдЖрдХрд╛рд░ рдФрд░ рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдХреЛрдб рдХреА рд╢реБрд░реБрдЖрдд рд╕реЗ рдСрдлрд╕реЗрдЯред

write_elf_phdr


 void write_elf_phdr(int fd, loader_t *loader, size_t payload_size) { //    Elf64_Phdr phdr; phdr.p_type = PT_LOAD; phdr.p_offset = 0; phdr.p_vaddr = 0; phdr.p_paddr = 0; phdr.p_filesz = sizeof(Elf64_Ehdr) + sizeof(Elf64_Phdr) + loader->loader_size + payload_size + AES_ENTROPY_BUFSIZE; phdr.p_memsz = phdr.p_filesz; phdr.p_flags = PF_R | PF_W | PF_X; phdr.p_align = 0x1000; write(fd, &phdr, sizeof(phdr)); //      } 

рдпрд╣рд╛рдВ, рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╣реЗрдбрд░ рдХреЛ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдлрд┐рд░ рдПрдХ рдлрд╛рдЗрд▓ рдкрд░ рд▓рд┐рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЖрдкрдХреЛ рдлрд╝рд╛рдЗрд▓ рдХреА рд╢реБрд░реБрдЖрдд рдФрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╣реЗрдбрд░ рджреНрд╡рд╛рд░рд╛ рд╡рд░реНрдгрд┐рдд рд╕реЗрдЧрдореЗрдВрдЯ рдХреЗ рдЖрдХрд╛рд░ рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖ рдСрдлрд╕реЗрдЯ рдкрд░ рдзреНрдпрд╛рди рджреЗрдирд╛ рдЪрд╛рд╣рд┐рдПред рдЬреИрд╕рд╛ рдХрд┐ рдкрд┐рдЫрд▓реЗ рдкреИрд░рд╛рдЧреНрд░рд╛рдл рдореЗрдВ рд╡рд░реНрдгрд┐рдд рд╣реИ, рдЗрд╕ рд╣реЗрдбрд░ рджреНрд╡рд╛рд░рд╛ рд╡рд░реНрдгрд┐рдд рд╕реЗрдЧрдореЗрдВрдЯ рдореЗрдВ рди рдХреЗрд╡рд▓ рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдХреЛрдб, рдмрд▓реНрдХрд┐ рдИрдПрд▓рдПрдл рд╣реЗрдбрд░ рдФрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╣реЗрдбрд░ рднреА рд╢рд╛рдорд┐рд▓ рд╣реИрдВред рд╣рдо рд▓реЗрдЦрди рдХреЗ рд▓рд┐рдП рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдХреЛрдб рдХреЗ рд╕рд╛рде рд╕реЗрдЧрдореЗрдВрдЯ рдХреЛ рднреА рд╕реБрд▓рдн рдмрдирд╛рддреЗ рд╣реИрдВ, рдпрд╣ рдЗрд╕ рддрдереНрдп рдХреЗ рдХрд╛рд░рдг рд╣реИ рдХрд┐ рдмреВрдЯрд▓реЛрдбрд░ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП рдПрдИрдПрд╕ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди "рдЬрдЧрд╣ рдореЗрдВ" рдбреЗрдЯрд╛ рдХреЛ рдПрдиреНрдХреНрд░рд┐рдкреНрдЯ рдФрд░ рдбрд┐рдХреНрд░рд┐рдкреНрдЯ рдХрд░рддрд╛ рд╣реИред

рдкреИрдХрд░ рдХреЗ рдХрд╛рдо рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рддрдереНрдп


рдкрд░реАрдХреНрд╖рдг рдХреЗ рджреМрд░рд╛рди, рдпрд╣ рджреЗрдЦрд╛ рдЧрдпрд╛ рдХрд┐ рдЗрд╕ рдирд┐рд░реНрджреЗрд╢ рдкрд░ рд╢реБрд░реВ рд╣реЛрдиреЗ рдкрд░ glibc рдХреЗ рд╕рд╛рде рд╕рдВрдХрд▓рд┐рдд рдХрд╛рд░реНрдпрдХреНрд░рдо рд╕реАрдЧрдлреЙрд▓реНрдЯ рдореЗрдВ рдЬрд╛рддреЗ рд╣реИрдВ:

  movq% fs: 0x28,% rax 

рдореБрдЭреЗ рдкрддрд╛ рдирд╣реАрдВ рдЪрд▓рд╛ рдХрд┐ рдРрд╕рд╛ рдХреНрдпреЛрдВ рд╣реЛрддрд╛ рд╣реИ, рдореБрдЭреЗ рдЦреБрд╢реА рд╣реЛрдЧреА рдЕрдЧрд░ рдЖрдк рдЗрд╕ рд╡рд┐рд╖рдп рдкрд░ рдЬрд╛рдирдХрд╛рд░реА рд╕рд╛рдЭрд╛ рдХрд░реЗрдВрдЧреЗред Glibc рдХреЗ рдмрдЬрд╛рдп, рдЖрдк musl-libc рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд╕рдм рдХреБрдЫ рдмрд┐рдирд╛ рдЕрд╕рдлрд▓рддрд╛ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдкреИрдХрд░ рдХреЛ рд╕рд╛рдВрдЦреНрдпрд┐рдХреАрдп рд░реВрдк рд╕реЗ рд╕рдВрдХрд▓рд┐рдд рдЧреЛрд▓рдВрдЧ рдХрд╛рд░реНрдпрдХреНрд░рдореЛрдВ рдХреЗ рд╕рд╛рде рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ http рд╕рд░реНрд╡рд░ред рдЧреЛрд▓рдВрдЧ рдХрд╛рд░реНрдпрдХреНрд░рдореЛрдВ рдХреА рдкреВрд░реНрдг рд╕реНрдерд┐рд░ рджреБрд░реНрдШрдЯрдирд╛рдУрдВ рдХреЗ рд▓рд┐рдП, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЭрдВрдбреЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП:

  CGO_ENABLED = 0 go -a -ldflags '-extldflags "-static"' рдЬрд╛рдУред 

рдбрд╛рдпрдирд╛рдорд┐рдХ рд▓рд┐рдВрдХрд░ рдХреЗ рдмрд┐рдирд╛ ET_DYN ELF рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд╕рд╛рде рдкреИрдХрд░ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рд╕рдЪ рд╣реИ, рдЗрди рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╕рдордп, elf_load_addr рдлрд╝рдВрдХреНрд╢рди рд╡рд┐рдлрд▓ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ, рдЗрд╕реЗ рдмреВрдЯрд▓реЛрдбрд░ рд╕реЗ рдХрд╛рдЯрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдкрддреЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП 0x10000ред

рдирд┐рд╖реНрдХрд░реНрд╖


рдпрд╣ рдкреИрдХрд░, рдЬрд╛рд╣рд┐рд░ рд╣реИ, рдЕрдкрдиреЗ рдЗрдЪреНрдЫрд┐рдд рдЙрджреНрджреЗрд╢реНрдп рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдордЭ рдореЗрдВ рдирд╣реАрдВ рдЖрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рдХреЗ рджреНрд╡рд╛рд░рд╛ рд╕рдВрд░рдХреНрд╖рд┐рдд рдлрд╛рдЗрд▓реЗрдВ рдЖрд╕рд╛рдиреА рд╕реЗ рдбрд┐рдХреНрд░рд┐рдкреНрдЯреЗрдб рд╣реИрдВред рдЗрд╕ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХрд╛ рдЙрджреНрджреЗрд╢реНрдп рдИрдПрд▓рдПрдл рдлрд╛рдЗрд▓реЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдмреЗрд╣рддрд░ рдорд╛рд╕реНрдЯрд░ рдереЗ, рдЙрдиреНрд╣реЗрдВ рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХрд╛ рдЕрднреНрдпрд╛рд╕, рд╕рд╛рде рд╣реА рдЕрдзрд┐рдХ рдкреВрд░реНрдг рдкреИрдХрд░ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреА рддреИрдпрд╛рд░реА рдХрд░рдирд╛ред

Source: https://habr.com/ru/post/hi483368/


All Articles