首页
社区
课程
招聘
[原创]破解之--函数调用栈逆向追踪
发表于: 2011-1-7 11:56 3959

[原创]破解之--函数调用栈逆向追踪

2011-1-7 11:56
3959
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
S表示是否栈指针
P表示是否是调用返回地址
H是否堆指针
E是否可执行代码
 
Address  Value    S P E H
-------------------------
0012FF7C 0012FF7C 1 0 0 0
0012FF80 004011F5 0 0 1 0
发现调用栈
TraceStack:004010D0 ip_ptr:004010D0 offset:-293
函数部分代码:
51 68 D0 70 40 00 8D 44
24 04 68 C8 70 40 00 68
B4 70 40 00 89 44 24 0C
E8 13 01 00 00 68 98 70
 
0012FF84 004012E5 0 0 1 0
发现调用栈
TraceStack:004010D0 ip_ptr:004011F0 offset:-245
函数部分代码:
E8 DB FE FF FF 33 C0 C3
90 90 90 90 90 90 90 90
53 56 BE 08 71 40 00 57
56 E8 4B 01 00 00 8B F8
 
0012FF88 00000001 0 0 0 0
0012FF8C 00381010 0 0 0 1
0012FF90 00381068 0 0 0 1
0012FF94 00241FE4 0 0 0 1
0012FF98 0012F7BC 1 0 0 0
0012FF9C 7FFDB000 0 0 0 0
0012FFA0 00000006 0 0 0 0
0012FFA4 F0A8ED04 0 0 0 0
0012FFA8 0012FF94 1 0 0 0
0012FFAC 865F204C 0 0 0 0
0012FFB0 0012FFE0 1 1 0 0
0012FFB4 00402878 0 0 1 0
0012FFB8 004060B0 0 0 1 0
0012FFBC 00000000 0 0 0 0
0012FFC0 0012FFF0 1 1 0 0
0012FFC4 7C817077 0 0 0 0
0012FFC8 00241FE4 0 0 0 1
0012FFCC 0012F7BC 1 0 0 0
0012FFD0 7FFDB000 0 0 0 0
0012FFD4 80545C7D 0 0 0 0
0012FFD8 0012FFC8 1 0 0 0
0012FFDC 856C7020 0 0 0 0
0012FFE0 FFFFFFFF 0 0 0 0
0012FFE4 7C839AD8 0 0 0 0
0012FFE8 7C817080 0 0 0 0
0012FFEC 00000000 0 0 0 0
0012FFF0 00000000 0 0 0 0
0012FFF4 00000000 0 0 0 0
0012FFF8 00401231 0 0 1 0
0012FFFC 00000000 0 0 0 0
-------------------------
 
当E=TRUE 且 *(unsigned char *)(Value-5)==0xE8 则 Value是调用栈 意思是如果此指针(Value)指向可执行代码,且所指向的位置Value-5个字节是CALL指令,
则Value是一个上层函数调用自己的的返回地址
 
找到当前函数的返回地址后, 我们在继续向上寻找上一个函数被调用后返回的地址,直到0012FFFF(栈底)
 
 
如何得到当前函数的代码?
 
unsigned char * ip_ptr=Value; 另ip_ptr=调用栈Value的值
 
ip_ptr-=5; //得到call指令首地址,属于假设,为了保证绝对是调用指令,需要判断第一个字符是否是0xEB
 
if (*ip_ptr==0xE8) //如果是相对CALL指令则
{
   ip_ptr++;
   int offset = *(int *)ip_ptr; 首先得CALL的偏移地址
 
   ip_ptr+=4;      //跳过当前指令再+
   ip_ptr+=offset; //计算出绝对地址
 
   //dump(ip_ptr,n) //显示当前函数16进制码
}
 
//实现代码
 
#include "stdafx.h"
#include <string.h>
 
int main(int argc, char* argv[]);
 
bool IsStackPointer(unsigned int p)
{
    return ( p>=0x00030000 && p<0x0012FFFF );
}
 
bool IsExeCode(unsigned int p)
{
    return ( p>=0x00400000 && p<0x005FFFFF );
}
 
bool IsHeapPointer(unsigned int p)
{
    return ( (p>=0x00130000 && p<0x003FFFFF ) || (p>=0x00600000 && p<0x0FFFFFFF)  );
}
 
void dump_mem(unsigned char * start, int len)
{
   int i;
   if(start == NULL) return ;
 
    
    for (i=0;i<len;i++)
    {
      printf("%02X ",start[i]);
      if (i%8==7) printf("\n");
    }
 
   printf("\n");
}
 
//获取调用自己的函数
void TraceStack()
{
     
    unsigned int *p;
 
    p=(unsigned int *)&p;
 
    printf("%-8s %-8s S P E H\n","Address","Value");
    printf("-------------------------\n");
    while((unsigned int)p<0x0012FFFF)
    {
        //if ( IsStackPointer(*p) && IsStackPointer(*p)?((unsigned int )p<*p):0)
        {
            printf("%08X %08X %d %d %d %d\n", p,*p, IsStackPointer(*p) , IsStackPointer(*p)?((unsigned int )p<*p):0 , IsExeCode(*p), IsHeapPointer(*p));
        }
 
        if (IsExeCode(*p))
        {
            unsigned char *ip_ptr=(unsigned char *)(*p);
 
            ip_ptr-=5;
 
            if (*ip_ptr==0xE8)
            {
                printf("发现调用栈\n",*ip_ptr);
 
                ip_ptr++;
 
                int offset=*(int *)ip_ptr;
 
                ip_ptr+=4;
 
                ip_ptr+=offset;
 
                printf("TraceStack:%08X ip_ptr:%08X offset:%d\n函数部分代码:\n", TraceStack, ip_ptr, offset);
 
                dump_mem(ip_ptr,32);
 
            }
 
             
        }
 
        p++;
    }
    printf("-------------------------\n");
}
 
 
int main(int argc, char* argv[])
{
    TraceStack();
 
    return 0;
}

[注意]看雪招聘,专注安全领域的专业人才平台!

收藏
免费
支持
分享
最新回复 (1)
雪    币: 208
活跃值: (40)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
太多地址硬编码
2011-1-9 12:26
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册