首页
社区
课程
招聘
[求助]CreateRemoteThread Debug异常而Release正常
发表于: 2013-6-24 00:09 6476

[求助]CreateRemoteThread Debug异常而Release正常

2013-6-24 00:09
6476
这段代码在VS2008 Win7下编译
Release 下通过
Debug下到WaitForSingleObject 有异常
0xC0000005: Access violation

本人新手+菜鸟
苦苦baidu&google半夜未果
求高手解答
Thanks in advance.
PS:
代码非本人写的
来自这里
http://win32.mvps.org/processes/remthread.html

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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
// demonstrates getting the command line of another process
// requires PROCESS_CREATE_THREAD, PROCESS_VM_OPERATION,
// PROCESS_VM_WRITE, PROCESS_VM_READ to the target, or the
// SeDebugPrivilege
 
// *** You *must* remove "/GZ" from the debug build settings ***
// (If you use my (felixk's) project file, this has already happened)
 
#include "stdafx.h"
 
 
#define lenof(x) ( sizeof (x) / sizeof ((x)[0]) )
 
typedef const wchar_t *(__stdcall *tGCLW)( void );
 
const DWORD MAXINJECTSIZE = 4096;
 
struct Common
{
  DWORD gle; // last error from remote thread
  tGCLW pGCLW; // address of GetCommandLineW()
  wchar_t str[2000]; // the command line buffer
};
 
 
// try to enable SeDebugPrivilege
void EnableDebugPriv( void );
// inject function bem() into target process
bool Bugger( HANDLE h, wstring &str );
// and this is the code we are injecting
DWORD __stdcall bem( Common *c );
 
 
int wmain( int argc, wchar_t *argv[] )
{
  int i;
  DWORD pid;
  HANDLE h;
  wstring str;
 
  if ( argc == 1 )
  {
    wcout << endl << L"usage: remthread pid [pid ...]" << endl;
    wcout << L"Reports the command lines of the specified processes." << endl;
    wcout << L"Use \"-1\" to have the program look at itself." << endl;
    return 1;
  }
 
  EnableDebugPriv();
  for ( i = 1; i < argc; ++ i )
  {
    wstringstream( argv[i] ) >> pid;
    if ( pid == (DWORD) -1 )
      pid = GetCurrentProcessId();
    wcout << L"pid " << pid << L": ";
    h = OpenProcess( PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION |
      PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, pid );
    if ( h != 0 )
    {
      if ( Bugger( h, str ) )
        wcout << endl << L"    \"" << str.c_str() << L"\"";
      CloseHandle( h );
      wcout << endl;
    }
    else
      wcout << L"open failed, gle = " << GetLastError() << endl;
  }
 
  return 0;
}
 
 
 
void EnableDebugPriv( void )
{
  HANDLE hToken;
  LUID sedebugnameValue;
  TOKEN_PRIVILEGES tkp;
 
  if ( ! OpenProcessToken( GetCurrentProcess(),
    TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ) )
  {
    wcout << L"OPT() failed, gle = " << GetLastError() <<
      L" SeDebugPrivilege is not available." << endl;
    return;
  }
 
  if ( ! LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &sedebugnameValue ) )
  {
    wcout << L"LPV() failed, gle = " << GetLastError() <<
      L" SeDebugPrivilege is not available." << endl;
    CloseHandle( hToken );
    return;
  }
 
  tkp.PrivilegeCount = 1;
  tkp.Privileges[0].Luid = sedebugnameValue;
  tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
 
  if ( ! AdjustTokenPrivileges( hToken, FALSE, &tkp, sizeof tkp, NULL, NULL ) )
    wcout << L"ATP() failed, gle = " << GetLastError() <<
      L" SeDebugPrivilege is not available." << endl;
 
  CloseHandle( hToken );
}
 
 
 
bool Bugger( HANDLE h, wstring &str )
{
  HANDLE ht = 0;
  void *p = 0;
  Common *c = 0;
  bool result = false;
  DWORD rc;
  HMODULE hk32 = 0;
  Common localCopy;
 
  // allocate memory
  p = VirtualAllocEx( h, 0, MAXINJECTSIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
  if ( p == 0 )
  {
    wcout << L"VAE() failed, gle = " << GetLastError();
    goto cleanup;
  }
 
  c = (Common *) VirtualAllocEx( h, 0, sizeof Common, MEM_COMMIT, PAGE_READWRITE );
  if ( c == 0 )
  {
    wcout << L"VAE() failed, gle = " << GetLastError();
    goto cleanup;
  }
 
  // copy function there
  if ( ! WriteProcessMemory( h, p, &bem, MAXINJECTSIZE, 0 ) )
  {
    wcout << L"WPM() failed, gle = " << GetLastError();
    goto cleanup;
  }
 
  // initialize data area for remote guy
  hk32 = LoadLibrary( L"kernel32.dll" );
  if ( hk32 == 0 )
  {
    wcout << L"LL() failed, gle = " << GetLastError();
    goto cleanup;
  }
  localCopy.gle = 0;
  localCopy.pGCLW = (tGCLW) GetProcAddress( hk32, "GetCommandLineW" );
  if ( localCopy.pGCLW == 0 )
  {
    wcout << L"GPA() failed, gle = " << GetLastError();
    goto cleanup;
  }
  FreeLibrary( hk32 );
  hk32 = 0;
  localCopy.str[0] = L'\0';
  if ( ! WriteProcessMemory( h, c, &localCopy, sizeof localCopy, 0 ) )
  {
    wcout << L"WPM() failed, gle = " << GetLastError();
    goto cleanup;
  }
 
  // CreateRemoteThread()
  ht = CreateRemoteThread( h, 0, 0, (DWORD (__stdcall *)( void *)) p, c, 0, &rc );
  if ( ht == NULL )
  {
    wcout << L"CRT() failed, gle = " << GetLastError();
    goto cleanup;
  }
 
  rc = WaitForSingleObject( ht, 3000 );
  switch ( rc )
  {
  case WAIT_TIMEOUT:
    wcout << L"WFSO() timed out. Odd!";
    goto cleanup;
  case WAIT_FAILED:
    wcout << L"WFSO() failed, gle = " << GetLastError();
    goto cleanup;
  case WAIT_OBJECT_0:
    // this might just have worked, pick up the result!
    if ( ! ReadProcessMemory( h, c, &localCopy, sizeof localCopy, 0 ) )
    {
      wcout << L"RPM() failed, gle = " << GetLastError();
      goto cleanup;
    }
    if ( localCopy.gle == 0 )
    {
      str = localCopy.str;
      result = true;
      wcout << L"successfully buggered.";
    }
    else
      wcout << L"Remote thread failed, gle = " << localCopy.gle;
    break;
  default:
    wcout << L"WFSO() returned a surprise! rc = " <<
      rc << L", gle = " << GetLastError();
    break;
  }
 
cleanup:
  CloseHandle( ht );
  if ( p != 0 )
    VirtualFreeEx( h, p, 0, MEM_RELEASE );
  if ( c != 0 )
    VirtualFreeEx( h, c, 0, MEM_RELEASE );
  if ( hk32 != 0 )
    FreeLibrary( hk32 );
 
  return result;
}
 
 
// The whole shebang makes a number of assumptions:
// -- target process is a Win32 process
// -- kernel32.dll loaded at same address in each process (safe)
// -- bem() shorter than MAXINJECTSIZE
// -- bem() does not rely on the C/C++ runtime
// -- /GZ is _not_ used. (If it is, the compiler generates calls
//    to functions which are not injected into the target. Oops!
DWORD __stdcall bem( Common *c )
{
  const wchar_t *src;
  wchar_t *tgt, *end;
 
  // __asm int 3;
  src = c->pGCLW();
  tgt = &c->str[0];
  end = &c->str[lenof( c->str ) - 1];
  if ( src == 0 || tgt == 0 || end == 0 )
  {
    c->gle = 998;
    return 0;
  }
 
  for ( ;  *src != L'\0' && tgt < end; ++ src, ++ tgt )
    *tgt = *src;
  *tgt = L'\0';
  c->gle = 0;
 
  return 0;
}

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费
支持
分享
最新回复 (5)
雪    币: 248
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
MARK下,我也遇到了这问题,未解决
2013-6-24 00:25
0
雪    币: 53
活跃值: (18)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
debug的link increment 去掉试试。
2013-6-24 00:28
0
雪    币: 202
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
去掉了可以通过了
请问原因是什么
谢谢!
2013-6-24 20:28
0
雪    币: 541
活跃值: (654)
能力值: ( LV12,RANK:250 )
在线值:
发帖
回帖
粉丝
5
我也得瑟一下。
一定不是WaitForSingleObject抛得异常。
其实是
1
2
// copy function there
 if ( ! WriteProcessMemory( h, p, &bem, MAXINJECTSIZE, 0 ) )

导致的问题,在远程线程执行的时候该线程抛0xC0000005.

这个问题是Debug版本编译的时候使用增量编译,导致每个函数都是用一个Thunk

你在Copy函数代码的时候,其实只Copy了Thunk,导致Copy的Thunk找不到函数真正的实体,从而崩溃。

用OD附加一下就知道答案了,遇到这种问题还是要自己动手调试解决
2013-6-25 09:47
0
雪    币: 202
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
Thanks a lot, man.
2013-6-25 23:01
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

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