反汇编

DNA图谱 / 问答 / 标签

用什么软件可以修改exe,dll文件内的反汇编程序,如何修改,请高手指教

ollydbg调试和修改exe等文件内部指令,使用IDA生成稍显易读的逆向代码。两者结合效果比较好。前者用于运行调试,找到目标指令的位置,后者则是逆向前期用来分析exe文件内部结构的工具。怎么改,不能一言蔽之。大概的原理可以告诉你使用ollydbg,运行,点击菜单栏的打开,选择你的exe文件,运行,找到main函数的位置,设置断点,单步运行,知道找到你想找的指令的位置,更改该指令,注意要保证指令的总体大小不变,比如说原先该条指令的大小是4个字节,那么你可以使用4个NOP指令代替,大小不变,但是使用6个NOP或者3个NOP指令,总体大小就不同了,exe文件内部指令的相对地址都变了。即最后的exe文件大小要不变,不然会损坏exe文件。。。最后保存修改的内容。不知道你有没有个大概的印象,反汇编本来就很耗时耗力,需要耐心和经验,还得看你的需求。你可以上“看雪论坛”搜索相关的教程。

怎样可以快速学会反汇编分析?

回复 1楼 天使联盟 的帖子这些东西可以去“看雪”或者“UpK”这两个论坛看看,技术挺不错的关键在于你要用反汇编去分析什么,完全没有目的一行一行的看汇编代码,谁都得吐血的……先确定一个目的,有了目的之后再根据目的去定位程序中的关键位置,然后去分析具体部分其实反汇编分析的入门阶段并不要求汇编水平有多高,基本汇编指令能看懂就OK,并不要求有基于汇编语言的开发背景加壳的东西可以去搜索脱壳的教程,自己分析的话需要对汇编算法和数据结构都很熟悉,一般压缩壳问题不大,F8一路跑下去就OK加密壳的话就看你的算法基础了。至于高级语言,反汇编Delphi程序蛮蛋疼的,不是Delphi语言的问题,而是Borland公司的编译器的问题(Borland C++编译的程序同样蛋疼)……简直就是call的浪费者,为了实现一个很小的功能,编译器能一层一层的向下call十几层……VB的东西就已经不能用蛋疼形容了……一般VB、.NET类的程序都有专门的反编译工具,不用反汇编的,都是直接反成高级语言进行分析。反汇编分析的基础建议从C/C++语言编译出的程序开始练起,尤其是VC编译出来的,比较标准,也很通用。自己编些最基础的控制台程序(比如只有一个简单循环的小程序,或者只有一个简单条件判断语句的小程序),然后自己用OD跟一下。能了解各种语句在反汇编中的汇编代码形式看雪一类的论坛有专门的CrackMe或者TraceMe的练习破解的小程序,可以用来练习破解、跟踪、脱壳等技能跟踪Win32程序进行行为分析的话,对Windows系统API的定位是非常实用的方法,能快速跟踪出程序的大体行为。至于快一点的方法——没有。成功没有捷径,技术是靠勤奋一点点积累起来的。

推荐几款C++和反汇编的书·· 简单点

反汇编,那就看点汇编的学吧,王爽汇编,图书并茂,看了就知道。之余C++的貌似经典中的还没什么图书并茂,简单的书了。《c++primer》此本已足够。在逆向方面看点,看点看雪的那个什么精华包就行了http://www.pediy.com/essay/PEDIY_CrackMe_2007.rarhttp://www.pediy.com/essay/pediy.com/pediy.com.zip

c++反汇编与逆向分析技术揭秘 crackme怎么无法运行

一、单类继承在父类中声明为私有的成员,子类对象无法直接访问,但是在子类对象的内存结构中,父类私有的成员数据依然存在。C++语法规定的访问限制仅限于编译层面,在编译过程中进行语法检查,因此访问控制不会影响对象的内存结构。子类未提供构造函数或析构函数,而父类却需要构造函数与析构函数时,编译器会为子类提供默认的构造函数与析构函数。但是子类有构造函数,而父类不存在构造函数,且没有虚函数,则编译器不会为父类提供默认的构造函数。1. 内存结构:①先安排父类的数据②后安排子类新定义的数据说明:基于上述的内存排列方法,即父类数据成员被安排前面。不管是父类的对象,还是子类的对象,父类的数据成员在内存中相对于对象的首地址的偏移值都是一样的。而且成员数据访问都是基于this指针间接寻址的。所以,对于子类对象而言,使用父类指针或者子类指针都可以正确访问其父类数据。2. 虚表:虚表的排列顺序是按虚函数在类继承层次中首次声明的顺序依次排列的。只要继承了父类,其派生类的虚函数表中的父类部分的排列就与父类一样。子类新定义的虚函数会按照声明顺序紧跟其后。3. 构造函数:①先调用父类构造函数②然后按照声明顺序调用成员数据变量的构造函数和初始化列表中指定的成员③最后再执行子类构造函数的函数体。说明:①父类构造函数,虚表指针修改为指向父类的虚表,所以在父类构造函数内调用虚函数,调用的是父类的虚函数。②子类构造函数,虚表指针修改为指向子类的虚表4. 析构函数:①先调用子类析造函数②然后成员对象的析构函数,按照声明的顺序以倒序方式依次调用成员对象的析构函数。③再执行父类构造函数说明:析构函数执行会首先设置虚表指针为自身虚表,再调用自身的析构函数。防止父类析构函数内调用子类对象的虚函数。类有派生与继承关系,需要声明析构函数为虚函数。若析构函数不是虚函数时,当使用父类指针指向堆中的子类对象,并使用delete释放对象空间时,编译器会按照指针类型调用父类的析构函数,从而引发错误。识别类之间的关系:先定位构造函数,根据构造先后顺序得到与之相关的其他类。再根据虚表,利用IDA中使用引用参考功能可得到所有的构造和析构函数。二、多重继承1. 内存排列:数据成员的排列顺序由继承父类的先后顺序所决定,从左向右依次排列。子类虚表指针的个数取决于所继承的父类的个数,有几个父类便对应几个虚表指针(虚基类除外)。将一个子类对象赋值给某个父类指针时,该父类指针便指向该父类所对应的虚表指针。三、单类继承与多重继承比较:单继承类在类对象占用的内存空间中,只保存一份虚表指针只有一个虚表指针,对应的也只有一个虚表虚表中各项保存了类中各虚函数的首地址构造时先构造父类,再构造自身,并且只调用一次父类构造函数析构时限析构自身,再析构父类,并且只调用一次父类析构函数多重继承类在类中所占用的内存空间中,根据继承父类的个数保存对应的虚表指针根据所保存的虚表指针的个数,对应产生相应个数的虚表。转换父类指针时,需要跳转到对象的首地址。构造时需要按照继承顺序调用多个父类构造函数。析构时先析构自身,然后以与构造函数相反的顺序调用所有父类的析构函数当对象作为成员时,整个类对象的内存结构和多重继承相似。当类中无虚函数时,整个类对象内存结构和多重继承完全一样,可酌情还原;当父类或成员对象存在虚函数时,通过过观察虚表指针的位置和构造函数、析构函数中填写虚表指针的数目及目标地址,来还原继承或成员关系。四、 示例1. 单类继承:C++源码1 #include <iostream>2 using namespace std;34 class Base {5 public:6 Base(){ nBase= 1;printf("CBase"); }7 ~Base(){ printf("~CBase"); }8 virtual void f() { printf("Base:f()");}9 virtual void g() { printf("Base:g()");}10 private:11 int nBase;12 13 };14 15 16 class Derive : public Base {17 public:18 Derive(){ nDerive=2;printf("Derive"); }19 ~Derive(){ printf("~Derive"); }20 virtual void g(){ printf("Dervie:g()");}21 virtual void h(){ printf("Dervie:h()");}22 private:23 int nDerive;24 };25 26 27 28 int main()29 {30 Derive d;31 Base *b = &d;32 b->g();33 return 0;34 } 汇编代码(VS2010编译)1. 内存分布1 类Derive对象2 0019FD30 0139583C =>.rdata:const Derive::`vftable"3 0019FD34 00000001 =>Base.nBase4 0019FD38 00000002 =>Derive.nDerive5 6 虚函数表7 0139583C 01391163 Base::f(void)8 01395840 0139110E Derive::g(void)9 01395844 013911AE Derive::h(void) 2. 构造函数1 pop ecx ;=>this指针出栈2 mov [ebp+this], ecx ;=>保存this指针3 mov ecx, [ebp+this] 4 call j_??0Base@@QAE@XZ ;=>调用基类构造函数Base::Base(void)5 mov eax, [ebp+this] ;=>eax=this指针6 mov dword ptr [eax], offset ??_7Derive@@6B@ ;=>初始化虚表指针为const Derive::`vftable"3. 析构函数1 pop ecx ;=>this指针出栈2 mov [ebp+this], ecx ;=>保存this指针3 mov eax, [ebp+this]4 mov dword ptr [eax], offset ??_7Derive@@6B@ ;=>重置虚表指针为const Derive::`vftable"5 mov esi, esp6 push offset aDerive ; "~Derive"7 call ds:__imp__printf8 add esp, 49 cmp esi, esp10 call j___RTC_CheckEsp11 mov ecx, [ebp+this] ;=>ecx传参this指针 12 call j_??1Base@@QAE@XZ ; =>调用基类析构函数 Base::~Base(void)2. 多重继承: C++源码1 #include <iostream>2 using namespace std;34 class Base1 {5 public:6 virtual void f() { cout << "Base1::f" << endl; }7 virtual void g() { cout << "Base1::g" << endl; }8 Base1(){b1 = 1; printf("Base1"); }9 ~Base1(){ printf("~Base1"); }10 private:11 int b1;12 13 };14 15 class Base2 {16 public:17 virtual void f() { cout << "Base2::f" << endl; }18 virtual void g() { cout << "Base2::g" << endl; }19 Base2(){b2 = 2; printf("Base2"); }20 ~Base2(){ printf("~Base2"); }21 private:22 int b2;23 };24 25 class Derive : public Base1, public Base2{26 public:27 virtual void f() { cout << "Derive::f" << endl; }28 virtual void g1() { cout << "Derive::g1" << endl; }29 Derive(){ d1 = 3; printf("Derive"); }30 ~Derive(){ printf("~Derive"); }31 private:32 int d1;33 34 };35 36 typedef void(*Fun)(void);37 38 int main()39 {40 41 Derive d;42 Base1 *b1 = &d;43 b1->f();44 b1->g();45 Base2 *b2 = &d;46 b2->f();47 b2->g();48 return 0;49 }汇编代码(VS2010编译) 1.内存分布;内存布局0019FA0C 008F584C ;=>.rdata:const Derive::`vftable"{for `Base1"} 第一个虚表0019FA10 00000001 ;=>Base1.b10019FA14 008F583C ;=>.rdata:const Derive::`vftable"{for `Base2"} 第二个虚表0019FA18 00000002 ;=>Base2.b20019FA1C 00000003 ;=>Derive.d1;虚函数表Derive::`vftable"{for `Base1"}00FB584C 00FB1041 ;=>Derive::f(void)00FB5850 00FB1118 ;=>Base1::g(void)00FB5854 00FB111D ;=>Derive::g1(void);虚函数表Derive::`vftable"{for `Base2"}00FB583C 00FB1113 ;=>Base2::g(void)00FB5840 00FB1028 ;=>[thunk]:Derive::f`adjustor{8}" (void)↓ ;追踪地址:00FB102800FB1028 jmp ?f@Derive@@W7AEXXZ ;=>[thunk]:Derive::f`adjustor{8}" (void)↓ ;追踪函数:?f@Derive@@W7AEXXZ00FB1F30 ?f@Derive@@W7AEXXZ proc near00FB1F30 sub ecx, 8 ;=>调整this指针 this = this+8,则this=>Derive::`vftable"{for `Base2"}00FB1F33 jmp j_?f@Derive@@UAEXXZ ;=>Derive::f(void)2.构造函数1 00FB14D9 mov [ebp-4], ecx ;=>this指针保存在esp-4处2 00FB14DC mov ecx, [ebp-4]   ;=>ecx获得this指针3 00FB14DF call j_??0Base1@@QAE@XZ ;=>调用构造函数 Base1::Base1(void)4 00FB14E4 mov ecx, [ebp-4]   ;=>ecx获得this指针5 00FB14E7 add ecx, 8    ;=>ecx获得this+86 00FB14EA call j_??0Base2@@QAE@XZ ;=>调用构造函数 Base2::Base2(void)7 00FB14EF mov eax, [ebp-4] ;=>eax获得this指针8 00FB14F2 mov dword ptr [eax], offset ??_7Derive@@6BBase1@@@ ;=>初始化第一个虚表指针为const Derive::`vftable"{for `Base1"}9 00FB14F8 mov eax, [ebp-4] ;=>eax获得this指针10 00FB14FB mov dword ptr [eax+8], offset ??_7Derive@@6BBase2@@@ ;=>初始化第二个虚表指针const Derive::`vftable"{for `Base2"}11 00FB1502 mov eax, [ebp-4] ;=>eax获得this指针12 00FB1505 mov dword ptr [eax+10h], 313 00FB150C push offset Format ; "Derive"14 00FB1511 call ds:__imp__printf15 00FB1517 add esp, 43.析构函数00FB17C9 mov [ebp-4], ecx ;=>this指针保存在esp-4处00FB17CC mov eax, [ebp-4] ;=>ecx获得this指针00FB17CF mov dword ptr [eax], offset ??_7Derive@@6BBase1@@@ ;=>重置第一个虚表指针为const Derive::`vftable"{for `Base1"}00FB17D5 mov eax, [ebp-4]00FB17D8 mov dword ptr [eax+8], offset ??_7Derive@@6BBase2@@@ ;=>重置第二个虚表指针为const Derive::`vftable"{for `Base2"}00FB17DF push offset aDerive ; "~Derive"00FB17E4 call ds:__imp__printf00FB17EA add esp, 400FB17ED mov ecx, [ebp-4] ;=>ecx获得this指针00FB17F0 add ecx, 8 ;=>ec;得this+800FB17F3 call j_??1Base2@@QAE@XZ ;=>调用虚构函数Base2::~Base2(void)00FB17F8 mov ecx, [ebp-4] ;=>ecx获得this指针00FB17FB call j_??1Base1@@QAE@XZ ;=>调用虚构函数Base1::~Base1(void)4.虚函数调用;Base1 *b1 = &d;00FB1431 lea eax, [ebp-14h] ;=>eax获得this指针00FB1434 mov [ebp-18h], eax ;=>局部变量b1赋值为this指针;b1->f();00FB1437 mov eax, [ebp-18h] ;=>eax获得b1值00FB143A mov edx, [eax] ;=>edx指向第一个虚表00FB143C mov ecx, [ebp-18h] ;=>ecx传递this指针00FB143F mov eax, [edx] ;=>eax获得成员函数Derive::f(void)的地址00FB1441 call eax ;=>调用成员函数Derive::f(void);b1->g();00FB1443 mov eax, [ebp-18h] ;=>eax获得b1值00FB1446 mov edx, [eax] ;=>edx指向第一个虚表00FB1448 mov ecx, [ebp-18h] ;=>ecx传递this指针00FB144B mov eax, [edx+4] ;=>eax获得成员函数Derive::g(void)的地址00FB144E call eax ;=>调用成员函数Derive::g(void);Base2 *b2 = &d;00FB1457 lea ecx, [ebp-14h] ;=>ecx获得this指针00FB145A add ecx, 8 ;=>ecx=this+8指向第二个虚表00FB145D mov [ebp-64h] ;=>保存ecx到临时变量中00FB1460 jmp short loc_FB1469 ;--|; |00FB1469 mov edx, [ebp-64h];<----| 00FB146C mov [ebp-1Ch], edx ;=>局部变量b2赋值为this+8;b2->f();00FB146F mov eax, [ebp-1Ch] ;=>eax获得b2值00FB1472 mov edx, [eax] ;=>edx获得指向第二个虚表00FB1474 mov ecx, [ebp-1Ch] ;=>ecx传递this+800FB1477 mov eax, [edx+4] ;=>eax为第二个虚表的第二个元素=>[thunk]:Derive::f`adjustor{8}" (void),间接调用Derive::f(void)00FB147A call eax;b2->g();00FB147C mov eax, [ebp+b2] ; =>eax获得b2值00FB147F mov edx, [eax] ;=>edx获得指向第二个虚表00FB1481 mov ecx, [ebp+b2] ;=>ecx传递this+800FB1484 mov eax, [edx] ;=>eax为第二个虚表的第一个元素=>Base2::g(void)00FB1486 call eax ;=>调用Base2::g(void)