您的位置:首页 > 其它

vc编译器,你在干什么?

2009-11-19 18:47 274 查看
学习编译原理。我们了解了很多关于高级语言转换为低级语言的变化过程。

其中编译可能对我们之前编写的程序进行了优化,这是我们不知道的。下面,看看微软的编译器,是怎么工作的。那么我们就可以更了解一个文件存放形式,和他原来的源代码的差别。当然有人可以通过了解这些汇编,得到一部分的源代码。进入修改程序得到自己想要的结果。

这个可以通过软件来实现,那么我们要明白其中的道理还是要回归到我们的原理出发点。

曾经有个案例,就是熊猫烧香,要是那个人学习了编译原理,或者知道程序的运行机制,那么他就不会因为自己的代码里面写了自己的相关资料而被捉起来了。

编译器是怎么让我们的高级语言变成汇编的呢? 我们知道了这些又应该怎么去防止别人将自己的代码反编译呢?在编译原理,和有汇编知识的人都可以知道。

00400000 dec ebp //看来00400000是一个编译程序的开始

004022B6 pop ebp
004022B7 ret //最后返回

纯粹过来贴下源代码:

#include <iostream>
using namespace std;
class base
{
public:
virtual void funb1()
{
cout << "funb1 base called." << endl;
}

void funb2()
{
cout << "funb2 base called." << endl;
}
};

class der : public base
{
public:
void funb1()
{
cout << "funb1 dev called." << endl;
}

//virtual //个人认为,这个virtual要去掉
void funb2()
{
cout << "funb2 dev called." << endl;
}
};

struct Coo
{
int d; //特意将d放在最前面,但其实它前面还有vtable

Coo ()
: d(100)
{}

virtual void foo();
};

void Coo::foo()
{}

int mayin()
{
base b;
der a;
der * pder = (der *)&b; //把一个基类对象,硬生生转换为派生类对象
der * fg = &a;
int *d=(int *)&b;
int *d2=(int *)&a;
int b1=*(int *)(*d);
int d1=*(int *)(*d2);

pder->funb1();
pder->funb2();

cout<<"b.funb2="<<b.funb2<<endl;
cout<<"b.funb1="<<b.funb1<<endl;
cout<<"*d="<< *d <<endl;
cout<<"*d2="<< *d2 <<endl;
cout << b1<<endl
<<d1<<endl;
cout<<"pder->funb1="<<pder->funb1<<endl
<<"pder->funb2="<<pder->funb2<<endl;

Coo o;
int *p = (int *)&o;
int addr = *(int *)(*p);
cout <<"*p=" <<*p << endl
<< o.d << endl
<<"addr="<<addr<<endl;

return 0;
}

class Coo1
{
public:
Coo1 ()
: d(100)
{}

private:
virtual void foo();   //私有的!
int d;
};

void Coo1::foo()
{
cout << d << "~~~!!!!~~~~" << endl;
}

int main()
{
Coo1 o;
int *p = (int *)(&o);
int addr = *(int *)(*p);

typedef void (* PFUNC)(Coo1*);
PFUNC pfunc = (PFUNC)(addr);
pfunc(&o); //hack! 调用了私有成员函数

return 0;
}


比较下的,汇编

00400000   dec         ebp
00400001   pop         edx
00400002   nop
00400003   add         byte ptr [ebx],al
00400005   add         byte ptr [eax],al
00400007   add         byte ptr [eax+eax],al
0040000A   add         byte ptr [eax],al
0040000C   ???
0040000D   inc         dword ptr [eax]
.
.
.
41:   #include <iostream>
42:   #include <ctime>
43:   #include <cstdlib>
44:   using namespace std;
45:
46:   int main()
47:   {
00401560   push        ebp
00401561   mov         ebp,esp
00401563   sub         esp,44h
00401566   push        ebx
00401567   push        esi
00401568   push        edi
00401569   lea         edi,[ebp-44h]
0040156C   mov         ecx,11h
00401571   mov         eax,0CCCCCCCCh
00401576   rep stos    dword ptr [edi]
48:       double random(double,double);
49:       srand(unsigned(time(0)));
00401578   push        0
0040157A   call        time (004207c0)
0040157F   add         esp,4
00401582   push        eax
00401583   call        srand (00420780)
00401588   add         esp,4
50:       for(int icnt = 0; icnt != 1000000; ++icnt)
0040158B   mov         dword ptr [ebp-4],0
00401592   jmp         main+3Dh (0040159d)
00401594   mov         eax,dword ptr [ebp-4]
00401597   add         eax,1
0040159A   mov         dword ptr [ebp-4],eax
0040159D   cmp         dword ptr [ebp-4],0F4240h
004015A4   je          main+79h (004015d9)
51:           cout << int(random(0,10))<<" ";
004015A6   push        offset string " " (0046f01c)
004015AB   push        40240000h
004015B0   push        0
004015B2   push        0
004015B4   push        0
004015B6   call        @ILT+630(random) (0040127b)
004015BB   add         esp,10h
004015BE   call        __ftol (00420a38)
004015C3   push        eax
004015C4   mov         ecx,offset std::cout (0047ce90)
004015C9   call        @ILT+245(std::basic_ostream<char,std::char_traits<char> >::operator<<) (004010fa)
004015CE   push        eax
004015CF   call        @ILT+625(std::operator<<) (00401276)
004015D4   add         esp,8
004015D7   jmp         main+34h (00401594)
52:       return 0;
004015D9   xor         eax,eax
53:   }
004015DB   pop         edi
004015DC   pop         esi
004015DD   pop         ebx
004015DE   add         esp,44h
004015E1   cmp         ebp,esp
004015E3   call        __chkesp (00420a00)
004015E8   mov         esp,ebp
004015EA   pop         ebp
004015EB   ret
--- No source file  --------
004015EC   int         3

...
55:   double random(double start, double end)
56:   {
00401610   push        ebp
00401611   mov         ebp,esp
00401613   sub         esp,4Ch
00401616   push        ebx
00401617   push        esi
00401618   push        edi
00401619   lea         edi,[ebp-4Ch]
0040161C   mov         ecx,13h
00401621   mov         eax,0CCCCCCCCh
00401626   rep stos    dword ptr [edi]
57:   return start+(end-start)*rand()/(RAND_MAX + 1.0);
00401628   fld         qword ptr [ebp+10h]
0040162B   fsub        qword ptr [ebp+8]
0040162E   fstp        qword ptr [ebp-8]
00401631   call        rand (00420790)
00401636   mov         dword ptr [ebp-0Ch],eax
00401639   fild        dword ptr [ebp-0Ch]
0040163C   fmul        qword ptr [ebp-8]
0040163F   fdiv        qword ptr [__real@8@400e8000000000000000 (0046f020)]
00401645   fadd        qword ptr [ebp+8]
58:   }
00401648   pop         edi
00401649   pop         esi
0040164A   pop         ebx
0040164B   add         esp,4Ch
0040164E   cmp         ebp,esp
00401650   call        __chkesp (00420a00)
00401655   mov         esp,ebp
00401657   pop         ebp
00401658   ret
--- No source file  ------------------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: