рд▓рд┐рдирдХреНрд╕ рдкрд░ рдореЗрдореЛрд░реА рд╕реЗ рдПрдХ рдЧрддрд┐рд╢реАрд▓ рдкреБрд╕реНрддрдХрд╛рд▓рдп рд▓реЛрдб рд╣реЛ рд░рд╣рд╛ рд╣реИ

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

рдЦреБрд▓реЗ, рдПрдордПрдордПрдкреА рдФрд░ рдЕрдиреНрдп рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд░реЛрдХрдирд╛ рдЕрд╕рдВрднрд╡ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ ld.so рдХреЛ рд╡реИрдзрд╛рдирд┐рдХ рд░реВрдк рд╕реЗ рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╕реЗ рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЙрдирдХреЗ рд▓реЛрдбрд░ рджреНрд╡рд╛рд░рд╛ рд▓реЛрдб рдХреА рдЧрдИ рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдлрд╛рдЗрд▓реЗрдВ "рдЕрд╡рд░" (рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ libdl рдореЗрдВ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдЕрд╡рд░реЛрдзрди рдХреЗ рд╕рд╛рде) рд╣реИрдВ, рд╡реЗ рд▓реЛрдб рдХрд┐рдП рдЧрдП рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдФрд░ / рдпрд╛ рдХреА рд╕реВрдЪреА рдореЗрдВ рдкрдВрдЬреАрдХреГрдд рдирд╣реАрдВ рд╣реИрдВред рдЙрдирдХреЗ рдЪрд░рд┐рддреНрд░ рдбреИрд▓реНрд╕рдо рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рджрд┐рдЦрд╛рдИ рдирд╣реАрдВ рджреЗрддреЗ рд╣реИрдВред рдирддреАрдЬрддрди, рдХреЗрд╡рд▓ рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдХрд╛ рдЕрд╡рд░реЛрдзрди рд░рд╣рддрд╛ рд╣реИред

рдмреВрдЯрд▓реЛрдбрд░ рдкреНрд░рд╡реЗрд╢ рдмрд┐рдВрджреБ:
void *dlopen_memory(void *base, size_t size, void *(*custom_dlopen)(const char *filename, void *arg), void *arg); 

рд╡рд┐рдХрд▓реНрдк:

рд╡рд╛рдкрд╕реА рдорд╛рди dlopen рдХреЗ рд╕рдорд╛рди рд╣реИ: рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╣реИрдВрдбрд▓ рдпрд╛ NULL рдФрд░ dlerror () рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рддреНрд░реБрдЯрд┐ рд╡рд┐рд╡рд░рдгред

рдпрд╣ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ:
  1. рдПрдХ рдЫрджреНрдо рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдирд╛рдо рдЙрддреНрдкрдиреНрди рд╣реЛрддрд╛ рд╣реИред рдореБрдЭреЗ рдмрд╕ рдпрд╣реА рдЪрд╛рд╣рд┐рдП, рдЕрдЧрд░ рдЖрдкрдХреЛ рдХреБрдЫ рдкрдардиреАрдп рдЪрд╛рд╣рд┐рдП - рдЕрддрд┐рд░рд┐рдХреНрдд рдкрд░ рдкрд╛рд╕ рдХрд░реЗрдВред рдлрд╝рд╛рдЗрд▓ рдирд╛рдо рдкреИрд░рд╛рдореАрдЯрд░ред
  2. рдЦрд╛рд▓реА SIGQUIT рд╕рд┐рдЧреНрдирд▓ рд╣реИрдВрдбрд▓рд░ рд╕реНрдерд╛рдкрд┐рдд рд╣реИ, рдкреБрд░рд╛рдирд╛ рдмрдЪрд╛ рд╣реИред рдмрд╛рдж рдореЗрдВ рдбрд╛рдЙрдирд▓реЛрдб рдкреВрд░рд╛ рд╣реЛрдиреЗ рдкрд░ рдЗрд╕ рд╕рд┐рдЧреНрдирд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
  3. рдПрдХ рдмрд╛рд▓ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдмрдирд╛рдИ рдЬрд╛рддреА рд╣реИ рдЬреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд▓реЛрдб рд╣реЛрдЧреАред
  4. рдмрд╛рд▓ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рддреИрдпрд╛рд░ рдЭрдВрдбреЗ рдХреА рд▓рдВрдмрд┐рдд рд╕реЗрдЯрд┐рдВрдЧред
  5. рд▓рд╛рдЗрдмреНрд░реЗрд░реА dlopen рдпрд╛ custom_dlopen рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд▓реЛрдб рд╣реЛ рд░рд╣реА рд╣реИред
  6. SIGQUIT рдХреЛ рдЕрдкрдиреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рднреЗрдЬрд╛ рдЬрд╛рддрд╛ рд╣реИред
  7. рдмрд╛рд▓ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдкреВрд░реА рд╣реЛрдиреЗ рдХреА рдЙрдореНрдореАрдж рд╣реИред
  8. SIGQUIT рд╣реИрдВрдбрд▓рд░ рдмрд╣рд╛рд▓ рд╣реИред

рдмрдЪреНрдЪреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреНрд░рд┐рдпрд╛рдПрдВ рдХрд░рддреА рд╣реИ:
  1. рдЕрдкрдиреЗ рдорд╛рддрд╛-рдкрд┐рддрд╛ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИред рдпрд╣ рдХреБрдЫ рджрд┐рд▓рдЪрд╕реНрдк рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреА рдУрд░ рдЬрд╛рддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╡рд╣ рдЕрдкрдиреЗ рдорд╛рддрд╛-рдкрд┐рддрд╛ рдХрд╛ рдкрд┐рддрд╛ рдмрди рдЬрд╛рддрд╛ рд╣реИред
  2. рдореВрд▓ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рддреИрдпрд╛рд░ рдзреНрд╡рдЬ рд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИред
  3. рдЬрдмрдХрд┐ рдореВрд▓ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЪрд▓ рд░рд╣реА рд╣реИ рдФрд░ рдПрдХ рд╕реНрдЯреЙрдк рдХрд╛ рдЕрдиреБрд░реЛрдз рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:
    1. рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рджрд░реНрдЬ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдореВрд▓ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЪрд▓рддреА рд╣реИред рдпрджрд┐ рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдПрдХ mmap рдЫрджреНрдо рдлрд╝рд╛рдЗрд▓ рдирд╣реАрдВ рд╣реИ, рддреЛ рдХреЙрд▓ рд╕реЗ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рднреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЪрд▓рддреА рд╣реИред
    2. рдмрд╛рд▓ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдХреЛ рдкреБрдирдГ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
    3. рдпрджрд┐ рдпрд╣ рдХреЙрд▓ рдореВрд▓ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рд▓рд┐рдП SIGQUIT рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИ, рддреЛ рдЯреНрд░реЗрд╕рд┐рдВрдЧ рдмрдВрдж рд╣реЛ рдЬрд╛рддреА рд╣реИред
    4. рдпрджрд┐ рдпрд╣ рдХреЙрд▓ рдПрдХ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдЫрджреНрдо рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдЙрджреНрдШрд╛рдЯрди рд╣реИ, рддреЛ рдЖрдЙрдЯрдкреБрдЯ рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░ рдХреЛ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░ рд╕реЗ рдмрджрд▓ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдЫрджреНрдо рдлрд╝рд╛рдЗрд▓ рдХреЗ рд╕рд╛рде рд╕рдВрдЪрд╛рд▓рди рдХреА рдкрд╣рдЪрд╛рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
    5. рдпрджрд┐ рдпрд╣ рдХреЙрд▓ рдПрдХ рдЫрджреНрдо рдлрд╛рдЗрд▓ рд╕реЗ рд░реАрдбрд┐рдВрдЧ рд╣реИ, рддреЛ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдЗрдореЗрдЬ рд╕реЗ рд▓реЗрдХрд░ рдкреЗрд░реЗрдВрдЯ рдкреНрд░реЛрд╕реЗрд╕ рдХреЗ рдмрдлрд░ рддрдХ рд░реАрдбрд┐рдВрдЧ рдХреА рдЬрд╛рддреА рд╣реИ рдФрд░ рдХреЙрд▓ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рдкреВрд░рд╛ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред
    6. рдпрджрд┐ рдпрд╣ рдХреЙрд▓ рдлрд╝рд╛рдЗрд▓ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИ, рддреЛ рдЫрджреНрдо рдлрд╝рд╛рдЗрд▓ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдЬрдирдХ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рдмрдлрд░ рдореЗрдВ рдЙрддреНрдкрдиреНрди рдФрд░ рд░рдЦреА рдЬрд╛рддреА рд╣реИ (рдЗрд╕рдореЗрдВ, рдХреЗрд╡рд▓ рдЖрдХрд╛рд░ рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ)ред
    7. рдпрджрд┐ рдпрд╣ рдХреЙрд▓ рдПрдХ рдлрд╝рд╛рдЗрд▓ рдХреЗ рдХрд░реАрдм рд╣реИ, рддреЛ рдХреЙрд▓ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рдкреВрд░рд╛ рд╣реЛрддрд╛ рд╣реИред
    8. рдпрджрд┐ рдпрд╣ рдХреЙрд▓ рдореЗрдореЛрд░реА рдореЗрдВ рдХрд┐рд╕реА рдЫрджреНрдо рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдорд╛рдирдЪрд┐рддреНрд░рдг рд╣реИ, рддреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреНрд░рд┐рдпрд╛рдПрдВ рдХреА рдЬрд╛рддреА рд╣реИрдВ:
      1. MAP_ANONYMOUS рдзреНрд╡рдЬ рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ (рд╕реНрдореГрддрд┐ рдХрд╛ рдПрдХ рдХреНрд╖реЗрддреНрд░ рдЬрд┐рд╕реЗ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдореИрдк рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ) рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред
      2. рдПрдордПрдордПрдкреА рдХреЙрд▓ рдЬрд╛рд░реА рд╣реИред
      3. рдореВрд▓ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдирд┐рд░реНрдорд┐рдд рдХреНрд╖реЗрддреНрд░ рдореЗрдВ, рдЫрджреНрдо рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдЕрдиреБрд░реЛрдзрд┐рдд рднрд╛рдЧ рдХреЙрдкреА рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред
  4. рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдкреИрд░реЗрдВрдЯ рд╕реЗ рдбрд┐рд╕реНрдХрдиреЗрдХреНрдЯ рд╣реЛ рдЬрд╛рддреА рд╣реИ рдФрд░ рдмрд╛рд╣рд░ рдирд┐рдХрд▓ рдЬрд╛рддреА рд╣реИред

рдпрд╣ рдХреЛрдб рдкреЛрд░реНрдЯреЗрдмрд▓ рдирд╣реАрдВ рд╣реИ рдФрд░ рдпрд╣ рдХреЗрд╡рд▓ рд▓рд┐рдирдХреНрд╕ рдкрд░ рдФрд░ рдХреЗрд╡рд▓ 32-рдмрд┐рдЯ рдореЛрдб рдореЗрдВ IA-32 рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдХреЗ рдкреНрд░реЛрд╕реЗрд╕рд░ рдкрд░ рдХрд╛рдо рдХрд░реЗрдЧрд╛ред рдПрдХ рдЕрд▓рдЧ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдХреЗ рд╕рд┐рд╕реНрдЯрдо рдХреЗ рд▓рд┐рдП, рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдХреЗ рдЕрдиреБрдХрд░рдг рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП (рдпрджрд┐ # # рдЕрдВрдд рдореЗрдВ рд░реИрдкрд┐рдВрдЧ) рдЖрд╡рд╢реНрдпрдХ рд╣реИ, рд╕рд┐рд╕реНрдЯрдо рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд▓рдЧ рд╢рдмреНрдж рд▓рдВрдмрд╛рдИ рдХреЗ рд╕рд╛рде, рддреЛ рдпрд╣ рднреА рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдХрд┐ рдкреАрдХрд╕реНрдЯреНрд░рд┐рдВрдЧ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдмрджрд▓рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдпрджрд┐ ptrace рдпрд╛ Waitpid рдкрд░ рдХреЙрд▓ рд╡рд┐рдлрд▓ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдорд╛рддрд╛-рдкрд┐рддрд╛ рдФрд░ рдмрдЪреНрдЪреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рджреЛрдиреЛрдВ рдХрд╛ рдХрд╛рдо рд╕рдорд╛рдкреНрдд рд╣реЛ рдЬрд╛рдПрдЧрд╛ред рдпрджрд┐ рдЖрдкрдХреЛ рдПрдХ рдЕрд▓рдЧ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдЕрд╕рдлрд▓ рд▓реЗрдмрд▓ рдХреЗ рдкреАрдЫреЗ рд╣реИрдВрдбрд▓рд░ рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦреЗрдВред

рдХреЛрдб рдмрд┐рдирд╛ рдХрд┐рд╕реА рдкреНрд░рддрд┐рдмрдВрдз рдХреЗ рдореБрдлреНрдд рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рдЙрдкрд▓рдмреНрдз рд╣реИред
 #include <sys/mman.h> #include <sys/ptrace.h> #include <string.h> #include <stdlib.h> #include <assert.h> #include <time.h> #include <stdio.h> #include <sched.h> #include <unistd.h> #include <signal.h> #include <sys/wait.h> #include <sys/user.h> #include <sys/syscall.h> #include <dlfcn.h> #include <errno.h> #include <limits.h> #include <fcntl.h> #include <sys/stat.h> #define min(a, b) ((a) < (b) ? (a) : (b)) static void generate_name(char *name, size_t length) { assert(length > 5); strcpy(name + length - 4, ".so"); for(unsigned int i = 1; i < length - 4; i++) name[i] = rand() % ('Z' - 'A' + 1) + 'A'; name[0] = '/'; } static void quit_handler(int sig) { (void) sig; } static int peekstring(pid_t pid, void *base, char *dest, size_t length) { unsigned int word; unsigned int offset = 0; do { word = ptrace(PTRACE_PEEKDATA, pid, base + offset, NULL); memcpy(dest + offset, &word, sizeof(unsigned int)); offset += sizeof(unsigned int); } while((word & 0xFF) && (word & 0xFF00) && (word & 0xFF0000) && (word & 0xFF000000) && offset < length); dest[length - 1] = 0; return 0; } static int pokedata(pid_t pid, void *address, const void *data, size_t length) { length = (length + sizeof(unsigned int) - 1) & ~(sizeof(unsigned int) - 1); const unsigned int *src = data; for(unsigned int offset = 0; offset < length; offset += sizeof(unsigned int)) { if(ptrace(PTRACE_POKEDATA, pid, address + offset, (void *) *src++) == -1) return -1; } return 0; } void *dlopen_memory(void *base, size_t size, void *(*custom_dlopen)(const char *filename, void *arg), void *arg) { char fakename[16]; int ready = 0; unsigned int offset = 0; generate_name(fakename, sizeof(fakename)); struct sigaction old_handler, new_handler = { .sa_handler = quit_handler, .sa_flags = 0, .sa_restorer = NULL }; sigfillset(&new_handler.sa_mask); if(sigaction(SIGQUIT, &new_handler, &old_handler) == -1) return NULL; pid_t child = fork(); if(child == -1) { sigaction(SIGQUIT, &old_handler, NULL); return NULL; } else if(child == 0) { pid_t parent = getppid(); if(ptrace(PTRACE_ATTACH, parent, NULL, NULL) == -1) { kill(parent, SIGKILL); _exit(1); } ready = 1; if(ptrace(PTRACE_POKEDATA, parent, &ready, (void *)ready) == -1) goto fail; int status; char path[PATH_MAX]; int handle = getdtablesize(); do { struct user_regs_struct regs; for(int i = 0; i < 2; i++) { if(ptrace(PTRACE_SYSCALL, parent, NULL, NULL) == -1) goto fail; if(waitpid(parent, &status, 0) == -1) goto fail; if(!WIFSTOPPED(status)) goto outer_break; if(ptrace(PTRACE_GETREGS, parent, NULL, ┬оs) == -1) goto fail; if(regs.orig_eax == SYS_mmap2 && regs.edi == handle) break; } if(regs.orig_eax == SYS_kill && regs.ebx == parent && regs.ecx == SIGQUIT) { break; } else if(regs.orig_eax == SYS_open) { if(peekstring(parent, (void *) regs.ebx, path, PATH_MAX) == -1) goto fail; if(strcmp(path, fakename) != 0) continue; regs.eax = handle; offset = 0; } else if(regs.orig_eax == SYS_read && regs.ebx == handle) { unsigned int bytes = min((unsigned int) regs.edx, size - offset); if(pokedata(parent, (void *) regs.ecx, base + offset, bytes) == -1) goto fail; offset += bytes; regs.eax = bytes; } else if(regs.orig_eax == SYS_close && regs.ebx == handle) { regs.eax = 0; } else if(regs.orig_eax == SYS_fstat64 && regs.ebx == handle) { struct stat statbuf = { .st_dev = 0, .st_ino = 1, .st_mode = 0444, .st_nlink = 1, .st_uid = 0, .st_gid = 0, .st_rdev = 0, .st_size = size, .st_blksize = 512, .st_blocks = (size + 511) & ~511, .st_atim = { 0, 0 }, .st_mtim = { 0, 0 }, .st_ctim = { 0, 0 } }; if(pokedata(parent, (void *) regs.ecx, &statbuf, sizeof(struct stat)) == -1) goto fail; regs.eax = 0; } else if(regs.orig_eax == SYS_mmap2 && regs.edi == handle) { regs.esi |= MAP_ANONYMOUS; if(ptrace(PTRACE_SETREGS, parent, NULL, ┬оs) == -1) goto fail; if(ptrace(PTRACE_SYSCALL, parent, NULL, NULL) == -1) goto fail; if(waitpid(parent, &status, 0) == -1) goto fail; if(!WIFSTOPPED(status)) break; if(ptrace(PTRACE_GETREGS, parent, NULL, ┬оs) == -1) goto fail; unsigned int offset = regs.ebp * 4096; unsigned int bytes = min(size - offset, (unsigned int) regs.ecx); if(pokedata(parent, (void *) regs.eax, base + offset, bytes) < 0) { regs.eax = -errno; if(ptrace(PTRACE_SETREGS, parent, NULL, ┬оs) == -1) goto fail; } continue; } else if(regs.orig_eax == -1) break; if(ptrace(PTRACE_SETREGS, parent, NULL, ┬оs) == -1) goto fail; } while(1); outer_break: ptrace(PTRACE_DETACH, parent, NULL, NULL); _exit(0); fail: ptrace(PTRACE_KILL, parent, NULL, NULL); _exit(1); } while(ready == 0) sched_yield(); void *handle; if(custom_dlopen) handle = custom_dlopen(fakename, arg); else handle = dlopen(fakename, RTLD_NOW); kill(getpid(), SIGQUIT); waitpid(child, NULL, 0); sigaction(SIGQUIT, &old_handler, NULL); return handle; } 

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


All Articles