反汇编的学习

首先看下凯撒加密算法的C++源代码,我们知道凯撒加密算法只是一个循环移位的算法,在这儿我们说这个,只是想学习下在反汇编过程当中遇到的问题,以及在反汇编过程中对

于循环等问题的处理,在此做下记录

// 凯撒加密算法.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include"iostream"
#include"time.h"
using namespace std;
int random;
char charTable[26];
char cipherText[260];
char claimText[260];
void encrypt()
{
	//首先获得移位的数目;
	srand(0);
	random=rand()%26;
	for(int i=0;i<strlen(claimText);i++)
	{
		char tmp=claimText[i];
		int index=-1;
		for(int j=0;j<26;j++)
		{
			if(tmp==charTable[j])
			{
				index=j;
				break;
			}
		}
		if(index!=-1)
		{
			cipherText[i]=(char)charTable[(index+random)%26];
		}
		else
		{
			cout<<"请您输入小写字母..."<<endl;
			break;
		}
	}
	cout<<"加密后的内容是:"<<cipherText<<endl;
}
void decipher()
{
	//进行解密,密文的索引+26然后减去random即是明文的索引
	int index=-1;
	for(int i=0;i<strlen(cipherText);i++)
	{
		
		for(int j=0;j<26;j++)
		{
			if(cipherText[i]==charTable[j])
			{
				index=j;
				break;
			}
		}
		if(index==-1)
		{
			cout<<"解密失败\n";
			return ;
		}
		else
		{
			index+=26;
			index-=random;
			index=index%26;
			claimText[i]=charTable[index];
		}
		index=-1;
	}
	cout<<"解密后的内容是:"<<claimText<<endl;

}
int _tmain(int argc, _TCHAR* argv[])
{
	//首先清零
	memset(cipherText,0,260);
	memset(claimText,0,260);
	//填充字母表
	char tmp=97;
	for(int i=0;i<26 i="" chartable="" i="" tmp="" tmp="" cin="">>claimText;
		encrypt();
		decipher();
	return 0;
}



  
  

这里只是C++源代码,我们还要分析,其反汇编的汇编代码

.text:00FA1000 ;
.text:00FA1000 ;
.text:00FA1000 ; +-------------------------------------------------------------------------+
.text:00FA1000 ; |   This file has been generated by The Interactive Disassembler (IDA)    |
.text:00FA1000 ; |        Copyright (c) 2009 by Hex-Rays, 
  
  
   
              |
.text:00FA1000 ; |                      License info: C0-F6AA-6380-12                      |
.text:00FA1000 ; |                              Licensed User                              |
.text:00FA1000 ; +-------------------------------------------------------------------------+
.text:00FA1000 ;
.text:00FA1000 ; Input MD5   : 178BC78F9435B75DF82D4B0244E89893
.text:00FA1000
.text:00FA1000 ; File Name   : D:\project\凯撒加密算法\Release\凯撒加密算法.exe
.text:00FA1000 ; Format      : Portable executable for 80386 (PE)
.text:00FA1000 ; Imagebase   : 400000
.text:00FA1000 ; Section 1. (virtual address 00001000)
.text:00FA1000 ; Virtual size                  : 000012E9 (   4841.)
.text:00FA1000 ; Section size in file          : 00001400 (   5120.)
.text:00FA1000 ; Offset to raw data for section: 00000400
.text:00FA1000 ; Flags 60000020: Text Executable Readable
.text:00FA1000 ; Alignment     : default
.text:00FA1000
.text:00FA1000                 include uni.inc ; see unicode subdir of ida for info on unicode
.text:00FA1000
.text:00FA1000                 .686p
.text:00FA1000                 .mmx
.text:00FA1000                 .model flat
.text:00FA1000
.text:00FA1000 ; ===========================================================================
.text:00FA1000
.text:00FA1000 ; Segment type: Pure code
.text:00FA1000 ; Segment permissions: Read/Execute
.text:00FA1000 _text           segment para public 'CODE' use32
.text:00FA1000                 assume cs:_text
.text:00FA1000                 ;org 0FA1000h
.text:00FA1000                 assume es:nothing, ss:nothing, ds:_data, fs:nothing, gs:nothing
.text:00FA1000
.text:00FA1000 ; =============== S U B R O U T I N E =======================================
.text:00FA1000
.text:00FA1000
.text:00FA1000 ; void __thiscall std__locale___locale(std::locale *this)
.text:00FA1000 public: __thiscall std::locale::~locale(void) proc near
.text:00FA1000                                         ; CODE XREF: __unwindfunclet$??$?5DU?$char_traits@D@std@@@std@@YAAAV?$basic_istream@DU?$char_traits@D@std@@@0@$$QAV10@PAD@Z$3+3j
.text:00FA1000 this = eax
.text:00FA1000                 mov     ecx, [this]
.text:00FA1002                 test    ecx, ecx
.text:00FA1004                 jz      short locret_FA101A
.text:00FA1006                 call    ds:std::locale::facet::_Decref(void)
.text:00FA100C                 test    this, this
.text:00FA100E                 jz      short locret_FA101A
.text:00FA1010                 mov     edx, [this]
.text:00FA1012                 mov     ecx, this
.text:00FA1014                 mov     this, [edx]
.text:00FA1016                 push    1
.text:00FA1018                 call    this
.text:00FA101A
.text:00FA101A locret_FA101A:                          ; CODE XREF: std::locale::~locale(void)+4j
.text:00FA101A                                         ; std::locale::~locale(void)+Ej
.text:00FA101A                 retn
.text:00FA101A public: __thiscall std::locale::~locale(void) endp
.text:00FA101A
.text:00FA101A ; ---------------------------------------------------------------------------
.text:00FA101B                 align 10h
.text:00FA1020
.text:00FA1020 ; =============== S U B R O U T I N E =======================================
.text:00FA1020
.text:00FA1020
.text:00FA1020 ; void __thiscall std__basic_ostream_char_std__char_traits_char_____Sentry_base____Sentry_base(std::basic_istream<char,std::char_traits
   
   
    
     >::sentry *this)
.text:00FA1020 public: __thiscall std::basic_ostream<char, struct std::char_traits
    
    
     
     >::_Sentry_base::~_Sentry_base(void) proc near
.text:00FA1020                                         ; CODE XREF: __unwindfunclet$??1sentry@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAE@XZ$0+3j
.text:00FA1020                                         ; __unwindfunclet$??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z$3+3j ...
.text:00FA1020 this = eax
.text:00FA1020                 mov     this, [this]
.text:00FA1022                 mov     ecx, [this]
.text:00FA1024                 mov     edx, [ecx+4]
.text:00FA1027                 mov     this, [edx+this+38h]
.text:00FA102B                 test    this, this
.text:00FA102D                 jz      short locret_FA1038
.text:00FA102F                 mov     edx, [this]
.text:00FA1031                 mov     ecx, this
.text:00FA1033                 mov     this, [edx+8]
.text:00FA1036                 jmp     this
.text:00FA1038 ; ---------------------------------------------------------------------------
.text:00FA1038
.text:00FA1038 locret_FA1038:                          ; CODE XREF: std::basic_ostream<char,std::char_traits
     
     
      
      >::_Sentry_base::~_Sentry_base(void)+Dj
.text:00FA1038                 retn
.text:00FA1038 public: __thiscall std::basic_ostream<char, struct std::char_traits
      
      
        >::_Sentry_base::~_Sentry_base(void) endp .text:00FA1038 .text:00FA1038 ; --------------------------------------------------------------------------- .text:00FA1039 align 10h .text:00FA1040 .text:00FA1040 ; =============== S U B R O U T I N E ======================================= .text:00FA1040 .text:00FA1040 ; Attributes: bp-based frame .text:00FA1040 .text:00FA1040 ; void __cdecl encrypt() .text:00FA1040 void __cdecl encrypt(void) proc near ; CODE XREF: _wmain+4Cp .text:00FA1040 push ebp .text:00FA1041 mov ebp, esp .text:00FA1043 and esp, 0FFFFFFF8h .text:00FA1046 push ecx .text:00FA1047 push ebx .text:00FA1048 push esi .text:00FA1049 push edi .text:00FA104A push 0 ; Seed .text:00FA104C call ds:__imp__srand .text:00FA1052 add esp, 4 .text:00FA1055 call ds:__imp__rand ; rand返回值放在EDI当中 .text:00FA105B cdq .text:00FA105C mov ecx, 1Ah ; ECX=26 .text:00FA1061 idiv ecx ; EDX当中放的是余数 .text:00FA1063 mov eax, offset char * claimText .text:00FA1068 xor ecx, ecx ; ECX清零 .text:00FA106A lea esi, [eax+1] .text:00FA106D mov edi, edx ; 将余数放在EDI当中 .text:00FA106F mov int random, edi ; random当中放的是EDX数据,也就是rand() .text:00FA1075 .text:00FA1075 loc_FA1075: ; CODE XREF: encrypt(void)+3Aj .text:00FA1075 mov dl, [eax] .text:00FA1077 inc eax .text:00FA1078 test dl, dl .text:00FA107A jnz short loc_FA1075 ; 该段代码用处是获得输入的数据的长度,放在eax当中 .text:00FA107C sub eax, esi .text:00FA107E mov esi, eax ; ESI当中也是claimText的长度 .text:00FA1080 jz short loc_FA10C1 ; 如果输入字符长度是0则直接跳转到输出 .text:00FA1082 .text:00FA1082 loc_FA1082: ; CODE XREF: encrypt(void)+D8j .text:00FA1082 mov dl, char * claimText[ecx] .text:00FA1088 xor eax, eax .text:00FA108A lea ebx, [ebx+0] .text:00FA1090 .text:00FA1090 loc_FA1090: ; CODE XREF: encrypt(void)+5Cj .text:00FA1090 cmp dl, char * charTable[eax] ; 找到charTable数组中的数据并与claimText中的数据进行比较 .text:00FA1096 jz short loc_FA10FA ; eax和-1进行比较,看看是否找到了claimText的数据 .text:00FA1098 inc eax .text:00FA1099 cmp eax, 1Ah .text:00FA109C jl short loc_FA1090 ; 该循环进行1A次,即26次 .text:00FA109E .text:00FA109E loc_FA109E: ; CODE XREF: encrypt(void)+BDj .text:00FA109E mov eax, ds:std::endl(std::basic_ostream<char,std::char_traits 
       
         > &) .text:00FA10A3 push eax .text:00FA10A4 push ecx .text:00FA10A5 mov ecx, ds:std::basic_ostream<char,std::char_traits 
        
          > std::cout .text:00FA10AB push offset _Val ; "请您输入小写字母..." .text:00FA10B0 push ecx ; _Ostr .text:00FA10B1 call std::operator<<<std::char_traits 
         
           >(std::basic_ostream<char,std::char_traits 
          
            > &,char const *) .text:00FA10B6 add esp, 0Ch .text:00FA10B9 mov ecx, eax .text:00FA10BB call ds:std::basic_ostream<char,std::char_traits 
           
             >::operator<<(std::basic_ostream<char,std::char_traits 
            
              > & (*)(std::basic_ostream<char,std::char_traits 
             
               > &)) .text:00FA10C1 .text:00FA10C1 loc_FA10C1: ; CODE XREF: encrypt(void)+40j .text:00FA10C1 ; encrypt(void)+DEj .text:00FA10C1 mov edx, ds:std::endl(std::basic_ostream<char,std::char_traits 
              
                > &) .text:00FA10C7 mov eax, ds:std::basic_ostream<char,std::char_traits 
               
                 > std::cout .text:00FA10CC push edx .text:00FA10CD push ecx .text:00FA10CE push offset char * cipherText ; _Val .text:00FA10D3 push ecx .text:00FA10D4 push offset aG ; "加密后的内容是:" .text:00FA10D9 push eax ; _Ostr .text:00FA10DA call std::operator<<<std::char_traits 
                
                  >(std::basic_ostream<char,std::char_traits 
                 
                   > &,char const *) .text:00FA10DF add esp, 0Ch .text:00FA10E2 push eax ; _Ostr .text:00FA10E3 call std::operator<<<std::char_traits 
                  
                    >(std::basic_ostream<char,std::char_traits 
                   
                     > &,char const *) .text:00FA10E8 add esp, 0Ch .text:00FA10EB mov ecx, eax .text:00FA10ED call ds:std::basic_ostream<char,std::char_traits 
                    
                      >::operator<<(std::basic_ostream<char,std::char_traits 
                     
                       > & (*)(std::basic_ostream<char,std::char_traits 
                      
                        > &)) .text:00FA10F3 pop edi .text:00FA10F4 pop esi .text:00FA10F5 pop ebx .text:00FA10F6 mov esp, ebp .text:00FA10F8 pop ebp .text:00FA10F9 retn .text:00FA10FA ; --------------------------------------------------------------------------- .text:00FA10FA .text:00FA10FA loc_FA10FA: ; CODE XREF: encrypt(void)+56j .text:00FA10FA cmp eax, 0FFFFFFFFh ; eax和-1进行比较,看看是否找到了claimText的数据 .text:00FA10FD jz short loc_FA109E ; 没找到,即,输入的不是小写字母 .text:00FA10FF add eax, edi ; edi是获得随机数的值 .text:00FA1101 cdq .text:00FA1102 mov ebx, 1Ah .text:00FA1107 idiv ebx .text:00FA1109 inc ecx ; 外层循环加1 .text:00FA110A mov dl, char * charTable[edx] ; dl中放的是charTable的数据,edx则是余数所在 .text:00FA1110 mov byte ptr (int random+3)[ecx], dl ; 将根据索引获得的值放在某一内存地址中 .text:00FA1116 cmp ecx, esi .text:00FA1118 jb loc_FA1082 ; ECX和ESI相比较,没有比较到claimText的最后 .text:00FA111E jmp short loc_FA10C1 ; 跳转输出 .text:00FA111E void __cdecl encrypt(void) endp .text:00FA111E .text:00FA1120 .text:00FA1120 ; =============== S U B R O U T I N E ======================================= .text:00FA1120 .text:00FA1120 ; Attributes: bp-based frame .text:00FA1120 .text:00FA1120 ; void __cdecl decipher() .text:00FA1120 void __cdecl decipher(void) proc near ; CODE XREF: _wmain+51p .text:00FA1120 push ebp .text:00FA1121 mov ebp, esp .text:00FA1123 and esp, 0FFFFFFF8h .text:00FA1126 push ecx .text:00FA1127 push ebx .text:00FA1128 push esi .text:00FA1129 mov eax, offset char * cipherText ; EAX获得cipherText的地址 .text:00FA112E push edi .text:00FA112F xor esi, esi ; ESI清零 .text:00FA1131 lea edx, [eax+1] ; edx获得eax+1 .text:00FA1134 .text:00FA1134 loc_FA1134: ; CODE XREF: decipher(void)+19j .text:00FA1134 mov cl, [eax] .text:00FA1136 inc eax .text:00FA1137 test cl, cl .text:00FA1139 jnz short loc_FA1134 .text:00FA113B sub eax, edx .text:00FA113D mov ebx, eax ; 计算cipherText的字符串长度,并且 .text:00FA113D ; EBX=strlen(cipherText) .text:00FA113F jz short loc_FA11B4 ; strlen(cipherText)=0则跳转 .text:00FA1141 mov edi, int random ; EDI=random .text:00FA1147 jmp short loc_FA1150 ; CL=cipherText[i] .text:00FA1147 ; --------------------------------------------------------------------------- .text:00FA1149 align 10h .text:00FA1150 .text:00FA1150 loc_FA1150: ; CODE XREF: decipher(void)+27j .text:00FA1150 ; decipher(void)+92j .text:00FA1150 mov cl, char * cipherText[esi] ; CL=cipherText[i] .text:00FA1156 xor eax, eax .text:00FA1158 .text:00FA1158 loc_FA1158: ; CODE XREF: decipher(void)+44j .text:00FA1158 cmp cl, char * charTable[eax] ; 外层循环是i=esi,内层循环是j=eax .text:00FA115E jz short loc_FA1181 ; 在charTable中找到了cipherText相对应的字符, .text:00FA115E ; eax是charTable的位置,看下eax是否等于-1,等于则失败 .text:00FA1160 inc eax .text:00FA1161 cmp eax, 1Ah .text:00FA1164 jl short loc_FA1158 ; 外层循环是i=esi,内层循环是j=eax .text:00FA1166 .text:00FA1166 loc_FA1166: ; CODE XREF: decipher(void)+64j .text:00FA1166 mov ecx, ds:std::basic_ostream<char,std::char_traits 
                       
                         > std::cout .text:00FA116C push offset aTZ ; "解密失败\n" .text:00FA1171 push ecx ; _Ostr .text:00FA1172 call std::operator<<<std::char_traits 
                        
                          >(std::basic_ostream<char,std::char_traits 
                         
                           > &,char const *) .text:00FA1177 add esp, 8 .text:00FA117A pop edi .text:00FA117B pop esi .text:00FA117C pop ebx .text:00FA117D mov esp, ebp .text:00FA117F pop ebp .text:00FA1180 retn .text:00FA1181 ; --------------------------------------------------------------------------- .text:00FA1181 .text:00FA1181 loc_FA1181: ; CODE XREF: decipher(void)+3Ej .text:00FA1181 cmp eax, 0FFFFFFFFh ; 在charTable中找到了cipherText相对应的字符, .text:00FA1181 ; eax是charTable的位置,看下eax是否等于-1,等于则失败 .text:00FA1184 jz short loc_FA1166 .text:00FA1186 sub eax, edi ; 找到了相应的位置,eax=J=J-random .text:00FA1188 lea ecx, [eax+1Ah] ; ECX=J-random+1A .text:00FA118B mov eax, 4EC4EC4Fh ; 从00ffa118b到00fa119c这段代码的作用 .text:00FA118B ; 如果eax即j-random<0 .text:00FA118B ; { .text:00FA118B ; ecx=j-random+26,eax=0; .text:00FA118B ; 119c之后edx本身就是charTable的地址 .text:00FA118B ; 取得是[charTable+j-random+26]的内容 .text:00FA118B ; } .text:00FA118B ; 否则的话 .text:00FA118B ; { .text:00FA118B ; eax=26,ecx=j-random+26 .text:00FA118B ; edx是charTable向前偏移26个字节的地址,最后取的是 .text:00FA118B ; [charTable-26+26+j-random]的内容 .text:00FA118B ; } .text:00FA118B ; .text:00FA1190 imul ecx .text:00FA1192 sar edx, 3 .text:00FA1195 mov eax, edx .text:00FA1197 shr eax, 1Fh .text:00FA119A add eax, edx .text:00FA119C imul eax, 1Ah .text:00FA119F mov edx, offset char * charTable .text:00FA11A4 sub edx, eax .text:00FA11A6 mov al, [edx+ecx] ; al中得到的是charTable[j-random]位置上的值 .text:00FA11A9 mov char * claimText[esi], al .text:00FA11AF inc esi .text:00FA11B0 cmp esi, ebx ; 查看外层循环是否结束 .text:00FA11B2 jb short loc_FA1150 ; CL=cipherText[i] .text:00FA11B4 .text:00FA11B4 loc_FA11B4: ; CODE XREF: decipher(void)+1Fj .text:00FA11B4 mov edx, ds:std::endl(std::basic_ostream<char,std::char_traits 
                          
                            > &) .text:00FA11BA mov eax, ds:std::basic_ostream<char,std::char_traits 
                           
                             > std::cout .text:00FA11BF push edx .text:00FA11C0 push ecx .text:00FA11C1 push offset char * claimText ; _Val .text:00FA11C6 push ecx .text:00FA11C7 push offset aTG ; "解密后的内容是:" .text:00FA11CC push eax ; _Ostr .text:00FA11CD call std::operator<<<std::char_traits 
                            
                              >(std::basic_ostream<char,std::char_traits 
                             
                               > &,char const *) .text:00FA11D2 add esp, 0Ch .text:00FA11D5 push eax ; _Ostr .text:00FA11D6 call std::operator<<<std::char_traits 
                              
                                >(std::basic_ostream<char,std::char_traits 
                               
                                 > &,char const *) .text:00FA11DB add esp, 0Ch .text:00FA11DE mov ecx, eax .text:00FA11E0 call ds:std::basic_ostream<char,std::char_traits 
                                
                                  >::operator<<(std::basic_ostream<char,std::char_traits 
                                 
                                   > & (*)(std::basic_ostream<char,std::char_traits 
                                  
                                    > &)) .text:00FA11E6 pop edi .text:00FA11E7 pop esi .text:00FA11E8 pop ebx .text:00FA11E9 mov esp, ebp .text:00FA11EB pop ebp .text:00FA11EC retn .text:00FA11EC void __cdecl decipher(void) endp .text:00FA11EC .text:00FA11EC ; --------------------------------------------------------------------------- .text:00FA11ED align 10h .text:00FA11F0 .text:00FA11F0 ; =============== S U B R O U T I N E ======================================= .text:00FA11F0 .text:00FA11F0 .text:00FA11F0 ; int __cdecl wmain(int argc, wchar_t **argv) .text:00FA11F0 _wmain proc near ; CODE XREF: __tmainCRTStartup+11Dp .text:00FA11F0 .text:00FA11F0 argc = dword ptr 8 .text:00FA11F0 argv = dword ptr 0Ch .text:00FA11F0 .text:00FA11F0 push 104h ; Size .text:00FA11F5 push 0 ; Val .text:00FA11F7 push offset char * cipherText ; Dst .text:00FA11FC call _memset .text:00FA1201 push 104h ; Size .text:00FA1206 push 0 ; Val .text:00FA1208 push offset char * claimText ; Dst .text:00FA120D call _memset .text:00FA1212 add esp, 18h .text:00FA1215 mov cl, 61h .text:00FA1217 xor eax, eax .text:00FA1219 lea esp, [esp+0] .text:00FA1220 .text:00FA1220 loc_FA1220: ; CODE XREF: _wmain+3Cj .text:00FA1220 mov char * charTable[eax], cl .text:00FA1226 inc eax .text:00FA1227 inc cl .text:00FA1229 cmp eax, 1Ah .text:00FA122C jl short loc_FA1220 .text:00FA122E mov eax, ds:std::basic_istream<char,std::char_traits 
                                   
                                     > std::cin .text:00FA1233 push eax ; _Istr .text:00FA1234 call ??$?5DU?$char_traits@D@std@@@std@@YAAAV?$basic_istream@DU?$char_traits@D@std@@@0@$$QAV10@PAD@Z .text:00FA1239 add esp, 4 .text:00FA123C call encrypt(void) ; 加密函数 .text:00FA1241 call decipher(void) ; 解密函数 .text:00FA1246 xor eax, eax ; 将eax置零,并作为返回值返回 .text:00FA1248 retn .text:00FA1248 _wmain endp .text:00FA1248 .text:00FA1248 ; ----------- 
                                    
                                   
                                  
                                 
                                
                               
                              
                             
                            
                           
                          
                         
                        
                       
                      
                     
                    
                   
                  
                 
                
               
              
             
            
           
          
         
        
      
     
     
    
    
   
   
  
  

还有就是我们知道计算字符串长度的方法1: mov eax, offset char * claimText lea esi, [eax+1] loc_FA1075 : mov dl, [eax] inc eax test dl, dl jnz short loc_FA1075 ; sub eax, esi根据字符串起始位置的地址,和根据字符串末尾位置的地址,这两者之间的偏移量即为字符串长度方法2:xor ecx,ecxloc_4755mov dl, char * claimText[ecx]test dl,dlinc ecxjnz short loc_4755最后ECX当中放的就是字符串长度

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

世纪殇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值