-
Notifications
You must be signed in to change notification settings - Fork 29
/
debug.c
142 lines (107 loc) · 3.23 KB
/
debug.c
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
/*
Copyright (C) 2011 Jay Satiro <[email protected]>
All rights reserved.
This file is part of GetHooks.
GetHooks is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
GetHooks is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GetHooks. If not, see <https://www.gnu.org/licenses/>.
*/
/**
This file contains functions to debug problems in GetHooks.
Each function is documented in the comment block above its definition.
-
dump_teb()
Dump to a file the thread environment block of a thread in another process.
-
*/
#pragma warning(disable:4996) /* 'function': was declared deprecated */
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include "util.h"
/* traverse_threads() */
#include "nt_independent_sysprocinfo_structs.h"
#include "traverse_threads.h"
#include "debug.h"
/* the global stores */
#include "global.h"
/* dump_teb()
Dump to a file the thread environment block of a thread in another process.
'pid' is the process id of the thread
'tid' is the thread id of the thread
'flags' are the thread traversal flags. currently only TRAVERSE_FLAG_DEBUG is checked
this function does not have any fatal path.
returns nonzero on success
*/
int dump_teb(
const DWORD pid, // in
const DWORD tid, // in
const DWORD flags // in, optional
)
{
size_t ret = 0;
FILE *fp = NULL;
void *buffer = NULL;
const unsigned filename_max = 80;
char *filename = NULL;
void *pvWin32ThreadInfo = NULL;
int return_code = 0;
SIZE_T buffer_size = 0;
if( !pid || !tid )
goto cleanup;
buffer = copy_teb_from_thread( pid, tid, flags, &buffer_size );
if( !buffer )
goto cleanup;
/* offsetof W32ThreadInfo: 0x40 TEB32, 0x78 TEB64 */
#ifdef _M_IX86
#define OFFSET_OF_W32THREADINFO 0x040
#else
#define OFFSET_OF_W32THREADINFO 0x078
#endif
pvWin32ThreadInfo = *(void **)( (char *)buffer + OFFSET_OF_W32THREADINFO );
filename = must_calloc( filename_max, sizeof( *filename ) );
_snprintf( filename, filename_max, "pid%u_tid%u_%p.teb", pid, tid, pvWin32ThreadInfo );
filename[ filename_max - 1 ] = 0;
SetLastError( 0 ); // error code is evaluated on success
fp = fopen( filename, "wb" );
if( ( flags & TRAVERSE_FLAG_DEBUG ) )
{
printf( "fopen() %s. filename: %s, GLE: %u, fp: 0x%p.\n",
( fp ? "success" : "error" ),
filename,
GetLastError(),
fp
);
}
if( !fp )
goto cleanup;
SetLastError( 0 ); // error code is evaluated on success
ret = fwrite( buffer, 1, buffer_size, fp );
if( ( flags & TRAVERSE_FLAG_DEBUG ) )
{
printf( "fwrite() %s. ret: %Iu, GLE: %u, fp: 0x%p.\n",
( ( ret == buffer_size ) ? "success" : "error" ),
ret,
GetLastError(),
fp
);
}
if( ret == buffer_size )
{
printf( "Dumped TEB to file %s\n", filename );
return_code = 1;
}
cleanup:
if( fp )
fclose( fp );
free( buffer );
free( filename );
return return_code;
}