百度空间 | 百度首页 
 
查看文章
 
编写稳定驱动之 编译器要注意的问题
2009年10月29日 星期四 15:06

先看一小段代码:

void   test_a()

{

int a = 1;

     __asm mov [ebp-4],8

int b =a;

int c = a;

     printff("--%d   %d\n",b,c);

}

DBUGERELEASE模式下编译这段代码,可以发现运行结果并不一样,

查看反汇编代码后,应该会发现问题, 那么在RELEASE模式下,int a = 1;

改为 volatile int a = 1;  再运行下看结果。

再看

int ig_a = 0;

int ig_b = 8;

void xxx(volatile int* x)

{

printf("--%d\n",*x);

}

void main()

{    

    int* iptr = (int*)&ig_a;

int il_a = 1;

    __asm mov [ebp - 4],11

printf("--%d\n", il_a);

xxx( iptr );

}

DBUGERELEASE模式下编译这段代码,可以发现运行结果一样

大家都知道 __asm mov [ebp - 4],11 句话话的意思吧, 就是给第一个参数的值赋值为11

C中,先声明的变量的地址比较高,所以[EBP-4]应该是 指 IPTR变量,但实际上

__asm mov [ebp - 4],11  在这里并不起到任何作用,很奇怪吧。

int il_a = 1; 改为 volatile int il_a = 1.。。再看看结果,奇怪吧。。

有时候我们写程序的逻辑编译器并不等于跟我们想的一样,特别是使用编译优化的时候。

比如

void res()

{

static int count   = 0;

count = count+2;

//// 一些不会操作到 count 的代码

     //////    QQQQQQQQQQQQQQQQQQQQ

count = count+2;

printf("--%d\n",count);

}

我们会以为这个输出是4,是的,从程序上看的确是4, 但是,如果你采用 RELEASE发行你的程序,并且这个函数会被多个线程掉用,那可能会有点问题。

反汇编看下

; 93    : static int count   = 1;

; 94    : count = count+2;

; 95    :

; 96    : //// 一些不会操作到 count 的代码

; 97    :

; 98    :

; 99    : count = count+2;

mov eax, DWORD PTR _?count@?1??res@@YAXXZ@4HA

add eax, 4

; 100   :

; 101   : printf("--%d\n",count);

push eax

push OFFSET FLAT:??_C@_05GJKK@?9?9?$CFd?6?$AA@ ; `string'

mov DWORD PTR _?count@?1??res@@YAXXZ@4HA, eax

call _printf

add esp, 8

好,我们知道 count的值最终放在寄存器 eax add eax, 4

假如执行到 add eax, 4,发生了中断, 线程调度程序 终止当前线程的执行,保存当前线程的上下文,注意,EAX ==4被保存了, 接着调度程序调用另一线程执行, 另一线程也 调用了 res()函数, count的值变了,因为是static int count,理论上这时候的值应该是 8,因为前面加4了嘛。假设线程也执行到 add eax, 4

被中止,这时候原来的线程被恢复执行,调用 printf("--%d\n",count); 结果输出是4,你会说,不对啊。。呵呵,对的, 因为  count的进行计算后的值是放到了 eax中,寄存器是线程相关的,所以count为静态变量而且即使其他线程也改了count,但原线程的输出还是4,并不会变换

总结: 在逆向,或者在驱动中编写的变量的值是可被改写的, 而且访问这些变量的函数时可以被多个线程调用的,应该要注意这种情况,一般时候我们不能老依赖编译器的优化,解决可以用 volatile 来定义变量,volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了,直接按地址访问,而不是寄存器,因为寄存器是线程相关,在多线程的环境下可能造成同步问题。


类别:默认分类 | 添加到搜藏 | 浏览() | 评论 (3)
 
最近读者:
 
网友评论:
1
2009年10月29日 星期四 15:18 | 回复
学习,细节的东西。。。。。
 
2
2009年10月29日 星期四 18:25 | 回复
“在 DBUGE和RELEASE模式下编译这段代码……”
 
3
2009年10月30日 星期五 16:28 | 回复
学习了, volatile
 
发表评论:
姓 名:
网址或邮箱: (选填)
内 容:
验证码: 请点击后输入四位验证码,字母不区分大小写
      

     

©2009 Baidu