рд╕рднреА рдХреЛ рдирдорд╕реНрдХрд╛рд░!
2010 рдореЗрдВ,
shoumikhin рдиреЗ рдПрдХ рдмрдврд╝рд┐рдпрд╛ рд▓реЗрдЦ,
рд╕рд╛рдЭрд╛ рдкреБрдирд░реНрднрд░рдг рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдореЗрдВ рдлрд╝реАрдЪрд░ рдкреБрдирд░реНрдирд┐рд░реНрджреЗрд╢рди рд▓рд┐рдЦрд╛ред рдпрд╣ рд▓реЗрдЦ рдмрд╣реБрдд рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИ, рдкреВрд░реНрдг рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рдЕрдзрд┐рдХ рдХрдЯреНрдЯрд░ рддрд░реАрдХреЗ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рд╣рдо рдбрд╛рдпрдирд╛рдорд┐рдХ рд▓рд┐рдВрдХрд░ рдХреЗ рдорд╛рдирдХ рдлреАрдЪрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ - рдкрд░реНрдпрд╛рд╡рд░рдг рдЪрд░ LD_PRELOAD, рдЬреЛ рдмрд╛рдХреА рд▓реЛрдб рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдЖрдкрдХреА рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЛ рд▓реЛрдб рдХрд░ рд╕рдХрддрд╛ рд╣реИред
рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ?
рд╣рд╛рдВ, рдпрд╣ рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИ - рд▓рд┐рдВрдХрд░ рдЖрдкрдХреЗ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЛ рдЖрдкрдХреЗ "рдорд╛рдирдХ" рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рдкрд╣рд▓реЗ рд▓реЛрдб рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдЬреЛ рдкрд╣рд▓рд╛ рд╣реИ - рд╡рд╣ рдФрд░ рдЪрдкреНрдкрд▓ред рдФрд░ рдЖрдк рдЕрдкрдиреА рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╕реЗ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдПрдХ, рдФрд░ "рдкреНрд░реЙрдХреНрд╕реА" рдХреЙрд▓ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд╕рд╛рде рд╣реА рд╕рд╛рде рдЬреЛ рдЪрд╛рд╣реЗрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рд░рд┐рдпрд▓ рдЙрдкрдпреЛрдЧ-рдХреЗрд╕ # 1: рдУрдкреЗрд░рд╛ рдореЗрдВ mimeinfo.cache рдХреЛ рдЕрд╡рд░реБрджреНрдз рдХрд░рдирд╛
рдореБрдЭреЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдУрдкреЗрд░рд╛ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдкрд╕рдВрдж рд╣реИред рдореИрдВ рдХреЗрдбреАрдИ рдХрд╛ рднреА рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВред рдУрдкреЗрд░рд╛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреЗрдбреАрдИ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреА рдкреНрд░рд╛рдердорд┐рдХрддрд╛рдУрдВ рдХрд╛ рд╕рдореНрдорд╛рди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдЕрдХреНрд╕рд░ рдПрдордХреЙрдо рдореЗрдВ рдбрд╛рдЙрдирд▓реЛрдб рдХрд┐рдП рдЧрдП рдЬрд╝рд┐рдк рд╕рдВрдЧреНрд░рд╣ рдХреЛ рдЦреЛрд▓рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддрд╛ рд╣реИ, рдкреАрдбреАрдПрдл рдореЗрдВ рдЗрдордЧреБрд░-рдЕрдкрд▓реЛрдбрд░, рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдЖрдк рдЬрд┐рд╕реНрдЯ рдХреЛ рдкрдХрдбрд╝рддреЗ рд╣реИрдВред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдЕрдЧрд░ рдЙрд╕реЗ mimeinfo.cache рдлрд╝рд╛рдЗрд▓ рдХреЛ рдкрдврд╝рдиреЗ рд╕реЗ рдордирд╛ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд╡рд╣ "kioclient exec" рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕рдм рдХреБрдЫ рдЦреЛрд▓ рджреЗрдЧреА, рдФрд░ рд╡рд╣ рдмреЗрд╣рддрд░ рдЬрд╛рдирддрд╛ рд╣реИ рдХрд┐ рдореИрдВ рдЗрд╕ рдпрд╛ рдЙрд╕ рдлрд╝рд╛рдЗрд▓ рдХреЛ рдХреНрдпрд╛ рдЦреЛрд▓рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдБред
рдХреЛрдИ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдлрд╝рд╛рдЗрд▓ рдХреИрд╕реЗ рдЦреЛрд▓ рд╕рдХрддрд╛ рд╣реИ? рджреЛ рдХрд╛рд░реНрдп рджрд┐рдорд╛рдЧ рдореЗрдВ рдЖрддреЗ рд╣реИрдВ:
рдЦреБрд▓рд╛ рдФрд░
рдЦреБрд▓рд╛ ред рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдУрдкреЗрд░рд╛ рдиреЗ 64-рдмрд┐рдЯ
рдлреЛрдкреЗрди рдПрдирд╛рд▓реЙрдЧ -
fopen64 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ ред рдЖрдк рдЗрд╕реЗ ltrace рдЙрдкрдпреЛрдЧрд┐рддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдпрд╛ рдмрд╕ objdump рдЙрдкрдпреЛрдЧрд┐рддрд╛ рдЖрдпрд╛рдд рддрд╛рд▓рд┐рдХрд╛ рдХреЛ рджреЗрдЦрдХрд░ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рд╣рдореЗрдВ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдХреНрдпрд╛ рдЪрд╛рд╣рд┐рдП? рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЖрдкрдХреЛ рдореВрд▓ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдПрдХ рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рдореЗрди рдлреЛрдкреЗрди рджреНрд╡рд╛рд░рд╛ рджреЗрдЦрддреЗ рд╣реБрдП, рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реИ:
FILE *fopen(const char *path, const char *mode)
рдФрд░ рдпрд╣ рдлрд╝рд╛рдЗрд▓ рдХреЛ рдирд╣реАрдВ рдЦреЛрд▓рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рддреЛ рдпрд╣ FILE рдпрд╛ NULL рдХреЛ рдПрдХ рдкреЙрдЗрдВрдЯрд░ рджреЗрддрд╛ рд╣реИред рдареАрдХ рд╣реИ, рдХреЛрдб рд▓рд┐рдЦреЗрдВ:
#define _GNU_SOURCE #include <stdio.h> #include <string.h> #include <dlfcn.h> static FILE* (*fopen64_orig)(const char * path, const char * mode) = NULL; FILE* fopen64(const char * path, const char * mode) { if (fopen64_orig == NULL) fopen64_orig = dlsym(RTLD_NEXT, "fopen64"); if (strstr(path, "mimeinfo.cache") != NULL) { printf("Blocking mimeinfo.cache read\n"); return NULL; } return fopen64_orig(path, mode); }
рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд╕рдм рдХреБрдЫ рд╕рд░рд▓ рд╣реИ: рд╣рдо fopen64 рдлрд╝рдВрдХреНрд╢рди рдХреА рдШреЛрд╖рдгрд╛ рдХрд░рддреЗ рд╣реИрдВ, рд╣рдорд╛рд░реЗ рд╕рдВрдмрдВрдз рдореЗрдВ "рдЕрдЧрд▓рд╛" (рдореВрд▓) рдлрд╝рдВрдХреНрд╢рди рд▓реЛрдб рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдЬрд╛рдВрдЪреЗрдВ рдХрд┐ рдХреНрдпрд╛ рд╣рдо "mimeinfo.cache" рдлрд╝рд╛рдЗрд▓ рдЦреЛрд▓ рд░рд╣реЗ рд╣реИрдВред рдЗрд╕реЗ рдирд┐рдореНрди рдХрдорд╛рдВрдб рдХреЗ рд╕рд╛рде рд╕рдВрдХрд▓рд┐рдд рдХрд░реЗрдВ:
gcc -shared -fPIC -ldl -O2 -o opera-block-mime.so opera-block-mime.c
рдФрд░ рдУрдкреЗрд░рд╛ рдЪрд▓рд╛рдПрдВ:
LD_PRELOAD=./opera-block-mime.so opera
рдФрд░ рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ:
Blocking mimeinfo.cache read Blocking mimeinfo.cache read Blocking mimeinfo.cache read Blocking mimeinfo.cache read
рд╕рдлрд▓рддрд╛!
рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЙрдкрдпреЛрдЧ-рдХреЗрд╕ # 2: рдХрд┐рд╕реА рдлрд╝рд╛рдЗрд▓ рдХреЛ рд╕реЙрдХреЗрдЯ рдореЗрдВ рдмрджрд▓рдирд╛
рдореЗрд░реЗ рдкрд╛рд╕ рдПрдХ рд╕реНрд╡рд╛рдорд┐рддреНрд╡ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд╣реИ рдЬреЛ рдкреНрд░рд┐рдВрдЯрд░ (рдбрд┐рд╡рд╛рдЗрд╕ рдлрд╝рд╛рдЗрд▓ / рджреЗрд╡ / рдпреВрдПрд╕рдмреА / рдПрд▓рдкреА 0) рддрдХ рд╕реАрдзреА рдкрд╣реБрдВрдЪ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдореИрдВ рдбрд┐рдмрдЧрд┐рдВрдЧ рдХреЗ рдЙрджреНрджреЗрд╢реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдЙрд╕рдХреЗ рд▓рд┐рдП рдЕрдкрдирд╛ рд╕рд░реНрд╡рд░ рд▓рд┐рдЦрдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ред рдХреНрдпрд╛ рдЦреБрд▓рд╛ () рд▓реМрдЯрддрд╛ рд╣реИ? рдлрд╝рд╛рдЗрд▓ рд╡рд┐рд╡рд░рдгрдХред рд╕реЙрдХреЗрдЯ () рдХреНрдпрд╛ рд▓реМрдЯрд╛рддрд╛ рд╣реИ? рдПрдХ рд╣реА рдлрд╛рдЗрд▓ рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░ рдЬреЛ рдкрдврд╝рддрд╛ рд╣реИ () рдФрд░ рд▓рд┐рдЦрддрд╛ рд╣реИ () рдареАрдХ рдЙрд╕реА рддрд░рд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдЖрд░рдВрдн рдХрд░рдирд╛:
#define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <dlfcn.h> #include <strings.h> #include <sys/socket.h> #include <netinet/in.h> static int (*orig_open)(char * filename, int flags) = NULL; int open(char * filename, int flags) { if (orig_open == NULL) orig_open = dlsym(RTLD_NEXT, "open"); if (strcmp(filename, "/dev/usb/lp0") == 0) { //opening tcp socket struct sockaddr_in servaddr, cliaddr; int socketfd = socket(AF_INET, SOCK_STREAM, 0); bzero(&servaddr,sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr=inet_addr("127.0.0.1"); // addr servaddr.sin_port=htons(32000); // port if (connect(socketfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == 0) printf("[Open] TCP Connected\n"); else printf("[Open] TCP Connection failed!\n"); return socketfd; } return orig_open(filename, flags); }
рдмрд╣реБрдд рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЙрдкрдпреЛрдЧ-рдХреЗрд╕ # 3 рдирд╣реАрдВ: C ++ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ рдЗрдВрдЯрд░рд╕реЗрдкреНрдЯ рдХрд░рдирд╛
C ++ рдХреЗ рд╕рд╛рде, рдЪреАрдЬреЗрдВ рдереЛрдбрд╝реА рдЕрд▓рдЧ рд╣реИрдВред рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рд╡рд░реНрдЧ рд╣реИ:
class Testclass { int var = 0; public: int setvar(int val); int getvar(); };
#include <stdio.h> #include "class.h" void Testclass() { int var = 0; } int Testclass::setvar(int val) { printf("setvar!\n"); this->var = val; return 0; } int Testclass::getvar() { printf("getvar! %d\n", this->var); return this->var; }
рд▓реЗрдХрд┐рди рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдкрд░рд┐рдгрд╛рдореА рдлрд╛рдЗрд▓ рдореЗрдВ "рдЯреЗрд╕реНрдЯрдХреНрд▓рд╛рд╕ :: рдЧреЗрдЯрд╡рд░" рдФрд░ "рдЯреЗрд╕реНрдЯрдХреНрд▓рд╛рд╕ :: рд╕реЗрдЯрд╡рд░" рдирд╣реАрдВ рдХрд╣рд╛ рдЬрд╛рдПрдЧрд╛ред рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдирд╛рдо рдЬрд╛рдирдиреЗ рдХреЗ рд▓рд┐рдП, рдмрд╕ рдирд┐рд░реНрдпрд╛рдд рддрд╛рд▓рд┐рдХрд╛ рджреЗрдЦреЗрдВ:
nm -D libclass.so тАж 0000000000000770 T _Z9Testclassv 00000000000007b0 T _ZN9Testclass6getvarEv 0000000000000780 T _ZN9Testclass6setvarEi
рдЗрд╕реЗ рдирд╛рдо рдореЗрдирд▓рд┐рдВрдЧ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред
рджреЛ рддрд░реАрдХреЗ рд╣реИрдВ: рдпрд╛ рддреЛ рд╕реА ++ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЛ рдПрдХ рдЗрдВрдЯрд░рд╕реЗрдкреНрдЯрд░ рдмрдирд╛рдПрдВ, рдХреНрд▓рд╛рд╕ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдирд╛ рдЬреИрд╕рд╛ рдХрд┐ рд╡рд╣ рдореВрд▓ рдореЗрдВ рдерд╛, рд▓реЗрдХрд┐рди рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЖрдкрдХреЛ рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдорд╕реНрдпрд╛ рдХреНрд▓рд╛рд╕ рдХреЗ рдХрд┐рд╕реА рд╡рд┐рд╢реЗрд╖ рдЙрджрд╛рд╣рд░рдг рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдореЗрдВ рд╣реЛрдЧреА, рдпрд╛ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдмрдирд╛рдиреЗ рдХреА рд╣реЛрдЧреАред рд╕реА рдореЗрдВ, рдирд┐рд░реНрдпрд╛рдд рдХреЗ рд░реВрдк рдореЗрдВ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдирд╛рдордХрд░рдг, рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдкрд╣рд▓рд╛ рдкреИрд░рд╛рдореАрдЯрд░ рдЖрдкрдХреЛ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдПрдХ рдкреЙрдЗрдВрдЯрд░ рдкрд╛рд╕ рдХрд░реЗрдЧрд╛:
#define _GNU_SOURCE #include <stdio.h> #include <dlfcn.h> typedef int (*orig_getvar_type)(void* instance); int _ZN9Testclass6getvarEv(void* instance) { printf("Wrapped getvar! %d\n", instance); orig_getvar_type orig_getvar; orig_getvar = (orig_getvar_type)dlsym(RTLD_NEXT, "_ZN9Testclass6getvarEv"); printf("orig getvar %d\n", orig_getvar(instance)); return 0; }
рд╡рд╣, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдореИрдВ рдЬреЛ рднреА рдмрд╛рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ред рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдпрд╣ рдХрд┐рд╕реА рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛ред