Soft-Ice version 2.0 and later: - Part One by CyberBobJr - 07/03/1998 Voilà une tache hardue ! vous expliquer comment fonctionne Soft-Ice sans aucunes docs officielles , on va y aller douçement et par le début, si vous lisez quelque chose de faux, faites moi le savoir par un email. Présentation générale : Soft-Ice est un debugger, il se charge bien avant Windows, c'est à dire qu'il prend en charge le code, bref c'est ler kernel du kernel, vous pouvez à tout moment basculer sous Soft-Ice et ainsi suivre un process en cours ... Soft-Ice n'est pas le seul debugger du marché, mais il a l'avantage de prend la main avant le windows, ce qui fait de lui le contrôleur principal du système. Ne vous attendez pas à avoir une belle interface graphique à la Windoz, si la vue des caractères systèmes vous donne des boutons, passez votre chemin, ces pages ne sont pas pour vous... Sous Soft-Ice tout est en mode texte, je vous rassure ce n'est pas du debug mais certaines notions d'assembleurs et de fonctionnement des registres sont indispensables. Installation : Vous pouvez trouver Soft-Ice dans de nombreuses pages on the Oueb, je n'ai ni le temps, ni l'envie d'uploader des centaines de Ko de fichiers sur ma page, on verra ça lorsque l'Isdn ou l'Adsl se seront généralisé, c'est à dire jamais tant que FT sera au pouvoir, bref ... La procédure d'installation est simple, vous double-cliquez sur Setup et le programme s'installera tout seul dans un répertoire nommé Siw95, il plaçera également dans la barre des programmes un zoli icone : le loader, une fois tous les fichiers copiés, il est très important de configuer Soft-Ice pour votre carte vidéo, sinon vous zaurez droit à un bel écran noir lors du basculement sous le debugger, pour çela rien de plus simple, il suffit de cliquer sur Soft-Ice driver setup, une fois la procédure réalisé il vous suffit de relancer la machine, et c'est parti ! au chargement vous verrez Soft-Ice se charger ... Petite précision, il est important de configurer Soft-Ice à ses goûts, et Soft-Ice dispose d'un fichier de configuration qui s'appelle Winice.dat, il se trouve dans le répertoire Siw95 ... Winice.dat renferme toute la configuration des touches macros, ne les modifiez pas, elles sont très pratiques et très souvent, dans les cours de cracks on nomme ces touches, elles sont devenues des 'standarts' en cracking, ce que vous pourrez modifier c'est dans cette partie : INIT = 'X;' Rajouter la commande suivante Code on, se qui vous permettra de voir directement le code en hexa des instructions que vous desassemblez : INIT = 'CODE ON;X;' Une chose importante, le chargement des symbols, c'est à dire le chargement des modules dll qui permettront à Soft-Ice de savoir à quoi correspond un hmemcpy ou un llseek, vous pouvez decommenter (en supprimant le ;) les lignes concernant les symboles pour win95 (chicago pour la version 2.00 de Soft-Ice), ce qui permettra de poser des breakpoints sur les fonctions incluses dans ces librairies. Notez que vous pouvez charger n'importe quelle Dll incluse avec un programme quelconque (cf cours sur Laplink). Voilà, c'est tout en ce qui concerne l'installation de Soft-Ice, nous allons maintenant aborder la procédure à suivre pour le lancement d'un programme à debugger. Lancement de Soft-Ice : Pour debugger un programme sous Soft-Ice, il faut le lancer par le loader, pour cela vous lancez le Loader et vous indiquez le fichier executable dans la zone prévue à cette effet, puis vous cliquez sur Load, si vous n'avez pas compris ca, je ne peux plus rien pour vous ... Au revoir ... non j'déconne, si vous ne comprenez pas ca, changez de processeur et faites vous en greffez un dans le cerveau, ou changez de système d'exploitation, rajoutez des modules mémoires ou changez de tête, essayez le ping-pong ou la broderie ;). Dans la série détails très cons : si le bouton load est grisé c'est que winice.exe n'a pas été lancé dans l'autoexec.bat ... ou encore c'est que vous n'avez pas rebooté votre machine après l'installation, si c'est le cas, voyez quelques lignes plus haut . Commandes utiles de base : X ou Ctrl-D ou F11 : execution du programme ? : Help (très important) T : trace pas à pas - c'est à dire execute le programme ligne par ligne, de ce fait on rentre dans les fonctions, les interruptions, les apis ... pour cela, le programme utilise l'interruption matérielle 01 qui lui permet de tracer un programme pas à pas. P ou F10 : step, execute le programme comme pour trace, mais il ne rentre pas dans les fonctions, les interruptions, les apis ... il les execute, step = pas, il fait un pas au-dessus des fonctions... compris ? BP... : placement de Breakpoint, ou point d'arrêt, comment ca marche ??? il faut savoir qu'il existe une interruption matérielle : la 03, qui permet de stopper un programme en cours d'execution, lorsque vous placez un breakpoint sur une adresse précise, Soft-Ice y place en fait une int 03, détournée bien sur, et de ce fait vous redonne la main à l'emplacement souhaité, en y replacant la ligne initiale bien entendu ... F12 : Permet de sortir d'un call et de revenir juste après l'instruction appelante du Call, c'est en fait une macro qui place un breakpoint sur l'adresse qui a appelé le call, pour ceux qui ne savent pas, lors d'un appel de call, le segment et l'offset de l'appel (CS:EIP) est placé sur la pile automatiquement par le processeur, le ret dépile ces adresse. Les breakpoints : Note : pour une lisibilité facile, les instructions seront en italiques, les paramètres obligatoires en gras et les paramètres optionnels entre crochets (les crochets ne doivent pas être mis quand vous tapez l'instruction !). Ils constituent une part importante dans le cracking d'un programme, c'est quasiment le nerf de guerre, il faut aboslument les maitriser pour (bien) contrôler le programme, voiçi quelques exemples : Bpx : Breakpoint on execution Syntaxe : Bpx adresse [C=count] Cette commande permet l'execution du programme jusqu'à adresse, count permet de définir le nombre d'itérations avant l'arrêt du programme à adresse, dans adresse vous pouvez définir soit une valeur explicite (ex: bpx 014F:023DF07C), soit un registre (ex: bpx cs:eip). Bpm : Breakpoint on memory Syntaxe : Bpm[B|W|D] adresse [R|W|RW|X] [qualifier value] [C=count] Le breakpoint on memory access peut-être de différent type : B pour un accès byte (1 octet par défaut), W pour word (2 octets) et D pour Double Word (4 octets). L'arrêt du programme se fera lorsqu'un accès mémoire se fera à adresse, l'accès peut être de type R (Read uniquement), W (Write, ecriture), RW (Lecture-ecriture), X (execution). Nous pouvons spécifier également la valeur dans la zone mémoire qui provoquera un breakpoint en spécifiant le paramètre [qualifier value] (ex: bpm ds:eax W eq 1 provoquera un breakpoint lorsque la zone située en ds:eax sera écrite avec la valeur hexadécimale 1), la syntaxe est la suivante : eq pour egal à, gt pour greater than (plus grand que)et lt pour less than (plus petit que), nous pouvons également spécifier un masque de bits (ex: bpm ds:eax W eq M 1xx0 00x1). Le paramètre count est identique au bpx. Bpr : Breakpoint on memory range Syntaxe : Bpr adresse1 adresse2 [R|W|RW|T|TW] [C=count] Le breakpoint on memory range vous permet de specifier toute une plage d'adresse dans laquelle Soft-Ice s'arrétera, les paramètres R,W,RW sont identiques au Bpm, idem pour le paramètre count. J'ignore à quoi serve les paramètres T et TW si quelqu'un à une idée => mail exemple : Bpr ds:eax ds:ebx R C=9 La zone mémoire située entre ds:eax et ds:ebx est sous le couvert d'un breakpoint, le programme donnera la main a Soft-Ice lorsque 9 accès aux données auront été fait. BPio : Breakpoint on i/o port Syntaxe : BPio port [R|W|RW] [qualifer value] [C=count] Breakpoint sur un port d'entrée/sortie, la syntaxe [R|W|RW] est identique à ce que nous avons vu précedemment, idem pour qualifer value et count. Le port doit être en hexadécimal. exemple : BPio 378 R Place un breakpoint sur toute tentative de lecture sur le port 378 (Lpt1) BPint : Breakpoint on Interruption Syntaxe : BPint interrupt-number [[AL|AH|AX]=value] [C=count] Voilà revenir nos chères interruptions du Dos, les interruptions du dos sont aux apis du windows, elles me permettent de me reperer dans un programme complexe, on sait où on se trouve ... Interrupt-number spécifie le numéro de l'interruption à 'breakpointer', en paramètres éventuels vous pouvez spécifier la zone inscrite dans le registre AL,AH ou AX, pour ce qui ne savent pas, AX peut contenir un paramètre definissant soit une sous-interruption (cf INT 21h qui contient au moins une 60aine de fonctions) soit un paramètre précis d'une autre intérruption. La valeur count est identique à ce que nous avons vu précedemment. exemple : BPint 13 Ah=02 Breakpoint sur l'interruption 13 (gestion des unités de disque), sous-fonction 02 (lecture d'un secteur précis sur un disque) . BMsg : Breakpoint on windows message Syntaxe : BMsg Window-handle [L] [begin-message [end-message]] [C=count] Breakpoint très important qui peut très souvent nous sortir d'un mauvais pas, on va y aller calmement et doucement : Le Window-handle est un numéro attribué par le système, c'est un numéro d'identifiant qui sert à repertorier un element (fenètre, boutton, boite de liste, etc...)pour visualiser l'ensemble des window-handle il faut taper la commande hwnd, ou hwnd programme_executable pour visualiser les handles attribués pour ce programme uniquement. Les messages windows sont standarts, ils ne peuvent changer, vous les trouverez tous par la commande wmsg, les messages peuvent-être soit explicite (ex : WM_LBUTTONUP) ou numérique (ex : 0202). Ainsi aussitôt qu'un message précis sera associé à un handle de fenêtre, Soft-Ice vous redonnera la main, il peut y avoir également un message de début et un message de fin... Mais nous y reviendrons quand moi-même j'aurais pigé ce truc. Le paramètre count est une fois de plus identique. exemple : Bmsg 04c8 WM_COMMAND Breakpoint aussitôt qu'une commande est passée à l'handle de la fenêtre (WM_COMMAND peut signifier une fermeture de l'handle, un bouton pressé, etc...). Soft-Ice version 2.0 and later: Part Two by CyberBobJr Addendum sur la première partie : A propos des Bpx : Il est possible de poser un breakpoint sur une api windows, ou sur tout autre fonction, a partir du moment où elle à été déclarée dans les exports de Soft-Ice, ces fonctions se trouvent généralement dans les Dll accompagnant un programme quelconque, pour cela il suffit de poser un bpx nomdelafonction (ex: bpx hmemcpy ou bpx getdlgitemtexta). Attention toutefois sur les apis windows, certaines sont contenues dans les modules user.dll et d'autres dans le module user32.dll, donc vérifier bien la syntaxe de votre bpx, au besoin vous pourrez vérifier la fonction par l'utilisation de la commande exp nomdelafonction qui vous donnera le nom du module qui l'a contient. A propos des Bpm : je vais prendre un exemple tout simple : Vous posez un bpx sur hmemcpy, pour récupérer une entrée clavier par exemple, vous tracez la fonction jusqu'a l'instruction movsw, vous notez l'adresse (par exemple 15d7:00000000) et vous posez un bpm dessus, vous relancez le programme et ... ca marche pas ! la raison en est simple : Soft-Ice à bien posé un bpm sur cette zone mémoire, mais votre programme n'y accede pas en utilisant l'adresse 15d7:00000000, or vous savez qu'une adresse mémoire peut être référencée par un segment:offset différent, et là, Soft-Ice ne sait pas ... donc pour résoudre le problème vous devez obtenir l'adresse linéaire de la mémoire, en particulier si vous utilisez 15d7:00000000, vous devez faire un page 15d7:00000000, cela vous donnera une adresse linéaire, il ne vous restera plus qu'a poser un bpm 0030:adresselinéaire, et voilà, votre breakpoint sera correctement posé. Toujours à propos du bpm, si vous posez un bpm adressememoire X , SoftIce vous donnera la main dés qu'une instruction est faite à cet emplacement mémoire, ca peut-être une bonne alternative au bpx si ca ne marche pas, ou si vous voulez entrez dans un module non-déclaré. Les BPM et les PBInt sont limités au nombre de 4 pour les processeurs Pentium et au-delà. Les expressions : La puissance de Soft-Ice provient également de ses macro commandes, nous allons voir comment utiliser les expressions pour poser des breakpoints, notons que la syntaxe est indentique à celle du C ou du C++. Voiçi la liste des instructions disponibles (pompée sur la doc ;) : Opérateur d'indirectionExemple ->ebp->8 (donne le dword pointé par ebp+8) .eax.1C (donne le dword pointé par eax+1c) **eax (donne la valeur dword pointée par eax) @@eax (idem .) Opérateur mathématiqueExemple /Si tu comprends pas, retourne à l'école !!! %Modulo << ou >>eax << 2 ou eax >> 1 (décalage de n bits) ?+Force la valeur en décimal (exe : ?+42) ?-Force la valeur en décimal (exe : ?-42) Opérateurs logiquesExemple !NOT logique &&AND Logique ||OR Logique ==Comparaison d'égalité !=Comparaison de différence Supérieur <=Inférieur ou égal >=Supérieur ou égal Les fonctions : certaines fonctions sont implémenté dans Soft-Ice, et vous permette de gagner du temps, voiçi la liste : FonctionExemple/commentaire ByteObtenir les bytes de poids faible (ex : ? byte (0x1234) = 0x34) WordObtenir le mot de poids faible (ex : ? word (0x12345678) = 0x5678) DwordIdem mais pour un double mot (ex : ? Dword (0xff) = 0x000000ff) HibyteOBtenir les bytes de poids forts (ex : ? hibyte (0x1234) =0x12) HiwordIdem mais pour un mot (ex : ? Hiword (0x12345678) = 0x12) SwordConverti un byte en mot signé (ex: ? sword (0x80) = 0xff80 LongConverti un byte en mot long signé (ex: ? long (0xff) = 0xffffffff) WSTRAffiche la chaine unicode (ex: ? WSTR(eax)) FlatConverti une adresse relative en une adresse adresse linéaire (ex: ? flat(fs:0) = 0xffdff000) CFLCarry flag (ex: ? CFL=type booléen) PFLParity flag AFLAuxiliary flag ZFLZero flag SFLSign flag OFLOverflow flag RFLResume flag TFLTrap flag DFLDirection flag IFLInterrupt flag NTFLNested Task flag DataAddrRetourne l'adresse du premier element affiché dans la zone data (ex: dd @dataaddr) CodeAddrRetourne l'adresse de la première instruction affichée dans la zone code (ex: ? codeaddr) ProcessKPEB (Kernel process Environnement Block) du process actif ThreadKTEB (Kernel Thread Environnement Block) du thread actif PIDId du process actif TID Id du thread actif BPcountNombre de breakpoints activés (cf plus bas) BPtotalNombre total de breakpoints (cf plus bas) BPmissNombre de breakpoints échoués ( cf plus bas) BPindexIndex du brekpoint actuel Les breakpoints : BPCount vous donne le nombre de breakpoint dont la valeur est TRUE, il faut savoir que si vous posez un breakpoint avec une condition, cette condition peut être rempli (BPCount++) ou non (BPmiss++), de ce fait vous pouvez encore avoir plus de contrôle sur le programme. BPtotal ne compte pas les réussis ou raté, il défini le nombre total de fois ou le programme va les activer ... exemple : Vous posez un BPX EIP IF (EAX==1), 2 possibilités se présentent : Le breakpoint s'active si eax==1 => BPCount++ Le breakpoint ne s'active pas car eax!=1 => BPmiss++ De toute façon BPtotal++ On peut donc être plus précis en disant : BPX EIP IF (EAX==1) && (BPCOUNT==5) Soft-Ice vous donnera la main lorsque eax=1 et que cette expression sera vérifiée 5 fois. L'instruction IF : L'instruction IF peut être utilisée de différentes manières, la première et la plus simple consiste à poser un breakpoint si et seulement si un registre contient une ou plusieurs valeurs, exemple : BPX EIP IF (EAX==1) // breakpoint en eip (pointeur courant) si le registre eax contient la valeur 1 BPX EIP IF (EAX==1) || (EBX==1) // breakpoint en eip si le registre eax=1 OU ebx=1 BPX EIP IF (EAX==1) && (EBX==1) // breakpoint en eip si le registre eax=1 ET ebx=1 Ici la première expression est déja évaluée (comme en C) puis la seconde... Et voilà, c'est fini pour le moment, il n'y a plus grand choz à dire maintenant sur Soft-Ice, kelkes bricoles pas forcement nécessaire pour notre combat. CyberBobJr