Question:
convertir cet ASM x86 en C?
user1365830
2013-05-26 00:15:24 UTC
view on stackexchange narkive permalink

Comment cet assemblage x86 32 bits pourrait-il être écrit en C?

  loc_536FB0: mov cl, [eax] cmp cl, '' jb short loc_536FBCcmp cl, ',' jnz short loc_536FBFloc_536FBC : mov byte ptr [eax], '' loc_536FBFmov cl, [eax + 1] inc eaxtest cl, cljnz short loc_536FB0  

J'ai déjà compris que c'est une boucle for qui boucle 23 fois avant de quitter.

Quatre réponses:
Igor Skochinsky
2013-05-26 01:11:41 UTC
view on stackexchange narkive permalink

Ces petits extraits ne sont pas trop difficiles à décompiler manuellement. Essayons-le.

Vous avez déjà compris que cl contient un caractère, cela signifie que eax d'où il est lu est un pointeur vers un caractère tableau. Appelons cela p . Maintenant, faisons une traduction stupide pour chaque instruction d'assembly en C:

  l1:; l1: mov cl, [eax]; cl = * p; cmp cl, ''; if (cl < '') jb short l2; goto l2cmp cl, ','; if (cl! = ',') jnz short l3; aller à l3l2:; l2: octet mov ptr [eax], ''; * p = '' l3:; l3: mov cl, [eax + 1]; cl = * (p + 1) inc eax; p = p + 1 test cl, cl; if (cl! = 0) jnz short l1; goto l1  

Et nettoyé:

  l1: cl = * p; if (cl < '') goto l2; if (cl! = ',') goto l3; l2: * p = ''; l3: cl = * (p + 1); p = p + 1; if (cl! = 0) goto l1;  

Maintenant, jetons un coup d'œil au deuxième if . Il a la forme suivante:

  if (condition) goto end_of_if; <if body>end_of_if:  

Et voici comment nous pouvons nous débarrasser du goto:

  if (! Condition) {<if body> }  

En l'appliquant à notre extrait de code:

  l1: cl = * p; if (cl < '') goto l2; si (cl == ',') {l2: * p = ''; } cl = * (p + 1); p = p + 1; if (cl! = 0) goto l1;  

Maintenant, comment pouvons-nous nous débarrasser de goto l2 ? Si vous l'examinez attentivement, vous pouvez voir que le corps en l2 sera exécuté si soit cl < '' ou cl == ',' . Nous pouvons donc simplement combiner les deux conditions avec un OU logique ( || ):

  l1: cl = * p; if (cl < '' || cl == ',') {* p = ''; }
cl = * (p + 1); p = p + 1; if (cl! = 0) goto l1;  

Il nous reste maintenant un goto . Nous avons: 1) une étiquette au début d'un bloc d'instructions 2) une vérification à la fin du bloc et 3) un retour au début du bloc si la vérification a réussi. C'est un modèle typique d'une boucle do-while , et nous pouvons facilement le convertir:

  do {cl = * p; if (cl < '' || cl == ',') {* p = ''; } cl = * (p + 1); p = p + 1; } while (cl! = 0)  

Maintenant, le code est presque beau et joli, mais nous pouvons le compresser un peu plus en substituant des instructions équivalentes:

  faire {si (* p < '' || * p == ',') * p = ''; cl = * ++ p;} while (cl! = 0)  

Et, enfin, la dernière affectation peut être déplacée dans la condition:

  do {if (* p < '' || * p == ',') * p = '';} while (* ++ p! = 0)  

Maintenant c'est évident ce que fait le code: il passe par la chaîne et remplace tous les caractères spéciaux (ceux avec des codes inférieurs à 0x20 aka espace) et les virgules par les espaces.

Excellente réponse, d'autant plus que vous expliquez chaque étape.
Réponse fantastique.
Je n'aurais pas pu faire mieux moi-même
* lit la réponse * "Wow, c'est vraiment détaillé et informatif, je me demande qui ..." * se rend compte que c'est le gars qui a procédé au reverse engineering d'Intel IME * "Ahhhhh ..."
Denis Laskov
2013-05-26 00:42:40 UTC
view on stackexchange narkive permalink

Et bien, spécialement pour ça, Hex-Rays Decompiler a été inventé. Il décompilera le code ASM en pseudo-C, et à partir de là, vous pourrez écrire une logique basée sur C du code d'assemblage que vous avez.

résolu ça maintenant
tout le monde n'a pas accès aux rayons hexagonaux mais ... La réponse d'Igor est beaucoup plus complète.
Eh bien, tout le monde n'a pas un petit extrait d'assemblage, la réponse doit donc être plus large qu'un cas spécifique. Et en effet merci Igor pour avoir passé son temps précieux pour ce morceau de code spécifique.
Non, vous n'avez pas répondu à la question. Si vous souhaitez créer un lien vers un outil qui rend la question obsolète, faites-le dans un commentaire sur la question.
oh, désolé, masa :)
Je crois que [Igor] (https://reverseengineering.stackexchange.com/users/60/igor-skochinsky) est un développeur pour Hex-Rays.
Tox1k
2013-05-26 02:23:39 UTC
view on stackexchange narkive permalink

Voici à quoi cela aurait ressemblé dans la source. Fastcall remplaçant la convention de feuille personnalisée que le compilateur utilisait lorsqu'il était optimisé.

  void __fastcall __forceinline RemoveControlChars (char * szInput) {int i; for (i = 0; i < 23 && * szInput; ++ i, ++ szInput) {if (* szInput < '' || * szInput == ',') * szInput = ''; }}  
Il n'y a rien que je puisse voir dans le code original qui corresponde à votre condition de continuation «i <24». Commencer à i = 0 et boucler tandis que i <24 exécutera également la boucle 24 fois, et non 23 comme indiqué par l'OP.
fastcall et forceinline ensemble n'ont aucun sens. S'il est en ligne, il n'y a pas de convention d'appel formelle.
__fastcall implique simplement que les arguments seront passés dans des registres plutôt que sur la pile, ce qui est supposé s'il est en ligne, mais le compilateur peut toujours pousser des arguments sur la pile s'il n'y a pas assez de registres, ce qui en fait une sorte d'anti-optimisation hackish. Selon msdn: `Même avec __forceinline, le compilateur ne peut pas intégrer de code dans toutes les circonstances.`
Not Star
2020-08-29 16:17:45 UTC
view on stackexchange narkive permalink

Vous pouvez utiliser le plugin r2dec sur radare2 avec la commande pdda

  [0x08048060] > pdda; montage | / * Sortie pseudo-code r2dec * / | / * ret @ 0x8048060 * / | #include <stdint.h> | ; (fcn) entrée0 () | int32_t entrée0 (void) {| faire {| / * [01] -r-x taille de section 23 nommée .text * / 0x08048060 mov cl, byte [eax] | cl = * (eax); 0x08048062 cmp cl, 0x20 | | if (cl > = 0x20) {0x08048065 jb 0x804806c | 0x08048067 cmp cl, 0x2c | | if (cl! = 0x2c) {0x0804806a jne 0x804806f | goto label_0; | } | } 0x0804806c octet mov [eax], 0x20 | * (eax) = 0x20; | label_0: 0x0804806f mov cl, octet [eax + 1] | cl = * ((eax + 1)); 0x08048072 inc eax | eax ++; 0x08048073 test cl, cl | 0x08048075 jne 0x8048060 | | } while (cl! = 0); | } [0x08048060] >  


Ce Q&R a été automatiquement traduit de la langue anglaise.Le contenu original est disponible sur stackexchange, que nous remercions pour la licence cc by-sa 3.0 sous laquelle il est distribué.
Loading...