This repository has been archived by the owner on Mar 21, 2021. It is now read-only.
/
scriptext.cpp
213 lines (174 loc) · 5.58 KB
/
scriptext.cpp
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
/*
Copyright (c) 2015 Piotr Stolarz
scriptext: Various scripting utilities WinDbg extension
Distributed under the GNU General Public License (the License)
see accompanying file LICENSE for details.
This software is distributed WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
*/
#include "common.h"
#include "string.h"
#include "file.h"
#include <errno.h>
/* DLL entry point */
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
BOOL ret=TRUE;
switch(fdwReason)
{
case DLL_PROCESS_ATTACH:
set_tls_i(TlsAlloc());
ret = (get_tls_i()!=TLS_OUT_OF_INDEXES);
break;
case DLL_PROCESS_DETACH:
if (get_tls_i()!=TLS_OUT_OF_INDEXES) TlsFree(get_tls_i());
break;
}
return ret;
}
/* Extension initialization */
HRESULT CALLBACK
DebugExtensionInitialize(PULONG Version, PULONG Flags)
{
*Version = DEBUG_EXTENSION_VERSION(1, 0);
*Flags = 0;
return S_OK;
}
#define MAX_PR_NAME 16
/* Get pseudo-reg name from flag arg and write it to the buffer 'pc_pr_name'
(min MAX_PR_NAME long)
*/
static BOOL get_pr_name(const flag_desc_t *p_flags_dsc, char *pc_pr_name)
{
BOOL ret=FALSE;
memset(pc_pr_name, 0, MAX_PR_NAME);
pc_pr_name[0]='$'; pc_pr_name[1]='t';
memcpy(pc_pr_name+2,
p_flags_dsc->pc_arg, min(p_flags_dsc->arg_len, MAX_PR_NAME-2));
pc_pr_name[MAX_PR_NAME-1]=0;
int pr_num = atoi(pc_pr_name+2);
if (!(pr_num>=0 && pr_num<20)) {
err_dbgprintf("Pseudo-reg number out of the range [0..19].\n");
goto finish;
}
ret=TRUE;
finish:
return ret;
}
/* sxtr input/pattern/replacement */
HRESULT CALLBACK sxtr(PDEBUG_CLIENT4 Client, PCSTR args)
{
HRESULT ret=E_FAIL;
set_client(Client);
flag_desc_t flags_dsc[] = {{'t', TRUE}, {0}};
size_t rd_sz = read_flags(args, flags_dsc);
args += rd_sz;
char pr_name[MAX_PR_NAME];
if (flags_dsc[0].is_pres) {
if (!get_pr_name(&flags_dsc[0], pr_name)) goto finish;
str_extr(args, pr_name);
} else {
str_extr(args, NULL);
}
ret=S_OK;
finish:
return ret;
}
/* fopn [-m mode] [-t num] fname */
HRESULT CALLBACK fopn(PDEBUG_CLIENT4 Client, PCSTR args)
{
HRESULT ret=E_FAIL;
set_client(Client);
flag_desc_t flags_dsc[] = {{'m', TRUE}, {'t', TRUE}, {0}};
size_t rd_sz = read_flags(args, flags_dsc);
args += rd_sz;
char mode[16] = "r+";
if (flags_dsc[0].is_pres) {
memcpy(mode,
flags_dsc[0].pc_arg, min(flags_dsc[0].arg_len, sizeof(mode)));
mode[sizeof(mode)-1]=0;
}
char pr_name[MAX_PR_NAME];
if (flags_dsc[1].is_pres) {
if (!get_pr_name(&flags_dsc[1], pr_name)) goto finish;
} else {
/* set default pseudo-reg */
strcpy(pr_name, "$t0");
}
if (file_open(args, mode, pr_name)) ret=S_OK;
finish:
return ret;
}
/* fwrt hndl input */
HRESULT CALLBACK fwrt(PDEBUG_CLIENT4 Client, PCSTR args)
{
HRESULT ret=E_FAIL;
set_client(Client);
ULONG64 fh_val;
if (!get_expression(args, &fh_val, &args)) goto finish;
for (; *args && isspace(*args); args++);
if (fh_val && file_wrtstr((FILE*)fh_val, args)) ret=S_OK;
finish:
return ret;
}
/* frdl hndl */
HRESULT CALLBACK frdl(PDEBUG_CLIENT4 Client, PCSTR args)
{
HRESULT ret=E_FAIL;
set_client(Client);
ULONG64 fh_val;
if (!get_expression(args, &fh_val, &args)) goto finish;
if (fh_val) file_rdln((FILE*)fh_val);
ret=S_OK;
finish:
return ret;
}
/* fcls hndl */
HRESULT CALLBACK fcls(PDEBUG_CLIENT4 Client, PCSTR args)
{
HRESULT ret=E_FAIL;
set_client(Client);
ULONG64 fh_val;
if (!get_expression(args, &fh_val, NULL)) goto finish;
if (!fh_val || fclose((FILE*)fh_val)) {
err_dbgprintf("File closure error\n");
} else ret=S_OK;
finish:
return ret;
}
/* help info */
HRESULT CALLBACK help(PDEBUG_CLIENT4 Client, PCSTR args)
{
set_client(Client);
dbgprintf(
"scriptext: Various scripting utilities\n\n"
"sxtr [-t num] input/pattern/replacement\n"
" Look for a substring of the input string matching the extended POSIX RE pattern.\n"
" If the pattern matches, the substring is extracted and modified according to\n"
" the replacement string. The input string may contain alphanumeric characters\n"
" plus '_' only, or must be enclosed in '' or \"\". If it's enclosed in [], then\n"
" the input string specifies an alias name containing a string to process.\n"
" Delimiter character is recognized as the first one after the input string. All\n"
" the strings may contain escaped characters.\n"
" -t: If specified, provides a pseudo-reg $t number where the matching result\n"
" will be set: 0 - not matched, 1 - matched.\n\n"
"fopn [-m mode] [-t num] fname\n"
" Open a file with a name fname.\n"
" -m: Open mode (C standard). \"r+\" by default.\n"
" -t: Pseudo-reg $t number where a handle of the opened file will be written. In\n"
" case of opening error zero will be written there. If not specified $t0 is\n"
" taken.\n"
"fwrt hndl input\n"
" Write the input string to the file with the handle hndl. If the input string\n"
" is enclosed in [] then it specifies an alias name containing a string to write.\n"
" The input string may contain escaped characters.\n"
"frdl hndl\n"
" Read line from a file with the handle hndl. The file shall be opened for read\n"
" in the text mode.\n"
"fcls hndl\n"
" Close a file with a handle hndl.\n\n"
"help\n"
" Display this help.\n");
return S_OK;
}