Intégration de code et danger de logiciels piratés

À propos de la façon dont vous pouvez incorporer du code sans jmp dans la section de code et rester invisible si vous n'étudiez pas le code complètement démonté. Peu importe, s'il vous plaît, sous le chat.

Je développe un désassembleur C pour Linux. À propos de moi, je ne dirais pas que je suis un programmeur professionnel. Je ne travaille pas en tant que programmeur, mais ce que j'ai appris c'est soit en lisant des livres, soit en l'inventant moi-même, soit en étudiant le code source d'autres programmes. Par conséquent, si le code vous semble enfantin, ne jurez pas.

Pour commencer, j'ai fait un désassembleur et mon code ressemble maintenant à ceci, c'est-à-dire qu'un octet est lu et passé à la fonction souhaitée.

void disasm_intel ( unsigned char *ptr, int size, int byte_order, int show ) { show_asm = show; virt = global_virt_text; unsigned char *start = ptr; start_op = ptr; for ( int index = 0; index < size; index++ ) { if ( show_asm == TRUE ) printf ( "%lx: ", virt ); switch ( *ptr ) { case 0x30: intel_opcode_1_0x30 ( &ptr, &index, byte_order ); break; case 0x31: intel_opcode_1_0x31 ( &ptr, &index, byte_order ); break; case 0x66: intel_opcode_1_0x66 ( &ptr, &index, byte_order ); break; case 0x67: intel_opcode_1_0x67 ( &ptr, &index, byte_order ); break; case 0x83: intel_opcode_1_0x83 ( &ptr, &index, byte_order ); break; case 0x88: intel_opcode_1_0x88 ( &ptr, &index, byte_order ); break; // mov register to register byte case 0x89: intel_opcode_1_0x89 ( &ptr, &index, byte_order ); break; case 0x8a: intel_opcode_1_0x8a ( &ptr, &index, byte_order ); break; case 0x8b: intel_opcode_1_0x8b ( &ptr, &index, byte_order ); break; // mov esp, %x : mov ebp, %x case 0x8d: intel_opcode_1_0x8d ( &ptr, &index, byte_order ); break; // lea case 0xb0: intel_opcode_1_0xb0 ( &ptr, &index ); break; // mov al, %x case 0xb1: intel_opcode_1_0xb1 ( &ptr, &index ); break; // mov cl, %x case 0xb2: intel_opcode_1_0xb2 ( &ptr, &index ); break; // mov dl, %x case 0xb3: intel_opcode_1_0xb3 ( &ptr, &index ); break; // mov bl, %x case 0xb4: intel_opcode_1_0xb4 ( &ptr, &index ); break; // mov ah, %x case 0xb5: intel_opcode_1_0xb5 ( &ptr, &index ); break; // mov ch, %x case 0xb6: intel_opcode_1_0xb6 ( &ptr, &index ); break; // mov dh, %x case 0xb7: intel_opcode_1_0xb7 ( &ptr, &index ); break; // mov bh, %x case 0xb8: intel_opcode_1_0xb8 ( &ptr, &index, byte_order ); break; // mov eax, %x case 0xb9: intel_opcode_1_0xb9 ( &ptr, &index, byte_order ); break; // mov ecx, %x case 0xba: intel_opcode_1_0xba ( &ptr, &index, byte_order ); break; // mov edx, %x case 0xbb: intel_opcode_1_0xbb ( &ptr, &index, byte_order ); break; // mov ebx, %x case 0xbe: intel_opcode_1_0xbe ( &ptr, &index, byte_order ); break; // mov esi, %x case 0xbf: intel_opcode_1_0xbf ( &ptr, &index, byte_order ); break; // mov edi, %x case 0xc3: intel_opcode_1_0xc3 ( ); break; // ret case 0xcd: intel_opcode_1_0xcd ( &ptr, &index ); break; // int 0x%x } ptr++; virt += ptr - start; start = ptr; start_op = ptr; } show_asm = FALSE; } 

Et ces fonctions sont déjà un tas. À certains endroits, j'ai fait des commentaires afin de rattraper l'interconnexion des instructions de la machine, et peut-être plus tard de faire un démonteur plus compétent. Mais sous cette forme, dans laquelle j'ai maintenant le code, je peux facilement définir toutes les conditions pour chaque opérateur.

Et donc pendant que je faisais cela, j'ai eu une idée, est-il possible d'ajouter du code au milieu de la section de code? Il s'avère que vous le pouvez, mais dans tous les cas? Jusqu'à présent, pour ajouter du code, j'utilise des codes machine déjà préparés. Si je peux plus tard, je ferai du traducteur assembleur en code machine pour ajouter du code était plus pratique. Dans mon cas, vous devez spécifier le décalage dans la section de code et les octets sont copiés au bon endroit. Il y avait aussi un certain problème: l'adressage en mémoire. J'ai ajouté un code à la commande lea qui enregistre les données nécessaires dans la structure, et si vous insérez de nouveaux opérateurs dans la section de code, tous les décalages sont alignés de manière à indiquer les données lors des nouveaux décalages. Eh bien, ce n'est pas très difficile, si vous insérez le code, la section de code augmentée du même nombre d'octets et toutes les autres sections après que la section de code contiendra déjà de nouveaux décalages. Je l'ai fait pour qu'il y ait des différences dans l'endroit où vous collez le code, tous les décalages fonctionnent correctement. Ensuite, le problème a surgi

 mov eax, [eax + eax + 0x100] 

Le fait est que dans un tel adressage, il peut y avoir ebp et pointer vers la pile, et non vers une autre section. J'ai décidé de faire en sorte que si l'adresse pointe vers la section de données, alors considérez les décalages lors de l'insertion du code, si elle pointe vers la pile, c'est-à-dire pas l'adresse dans la section de données, alors ne prenez pas en compte les décalages.

Et de cette façon, les attaquants peuvent en profiter. Après tout, un code malveillant peut être inséré au début d'une fonction dans le programme, par exemple, afin qu'un enfant fork soit créé et qu'un fichier spécial soit téléchargé. Sous Linux, cela peut se faire sans aucun problème. En effet, dans / usr / include il y a un fichier avec toutes les fonctions système du système d'exploitation. Autrement dit, vous pouvez utiliser la partie réseau, même si le programme n'a pas de fonctions réseau. Je ne sais pas comment dans Windows, mais je vais essayer d'ajouter du travail avec le format pe plus tard. Il peut s'avérer faire la même chose que sous Linux. Jusqu'à présent, j'ai une version console. Mais alors je prévois de faire sur gtk.

Merci d'avoir consacré votre temps à mon article.

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


All Articles