-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathperldll.cpp
executable file
·161 lines (146 loc) · 4.18 KB
/
perldll.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
/* vim:set ts=4 sw=4:
*
* (C) 2008 Willem Hengeveld itsme@xs4all.nl
*
* IdcPerl - a perl scripting plugin for the Interactive Disassembler by hex-rays.
* see http://www.xs4all.nl/~itsme/projects/idcperl
*
* this module contains code that dynamically imports all functions from DYNAMIC_PERL_DLL
*
*/
#include <string>
#include "perldll.h"
struct PerlFuncDef {
char* name;
FARPROC* ptr;
};
// ida includes
#include "pro.h" // for basic types.
#include "ida.hpp" // for ida constants and types.
#include "idp.hpp" // for interface version
#include "netnode.hpp" // for RootNode
#include "expr.hpp" // for IDCFuncs
// perl includes
#include "extern.h"
#include "perl.h"
#include "xsub.h"
#undef do_open
#undef do_close
#include "redefperlasdll.h"
#include <shlwapi.h> // FilePathExists
#ifdef TRACE_DLL
#define tracemsg msg
#else
#define tracemsg(...)
#endif
// empty def, this is the module defining the function ptrs.
#define PERLDEFINE
#include "perldllprocs.h"
static PerlFuncDef perl_funcname_table[] = {
#include "perldllprocnames.inc"
};
bool PerlDll::load_procs()
{
for (PerlFuncDef *p=perl_funcname_table ; p->ptr ; p++)
{
*p->ptr = GetProcAddress(_h, p->name);
if (*p->ptr==NULL)
{
msg("IDAPERL ERROR loading proc %s\n", p->name);
return false;
}
}
return true;
}
void PerlDll::unload()
{
tracemsg("PerlDll::unload\n");
if (_h) {
PERL_SYS_TERM();
FreeLibrary(_h);
_h = NULL;
}
}
bool search_regkey(HKEY hKey, const std::string& regpath, const std::string& name, std::string& dllname)
{
HKEY hKeyAP;
LONG rc;
rc= RegOpenKeyEx(hKey, regpath.c_str(), 0, KEY_READ, &hKeyAP);
if (rc==0) {
DWORD dllnamesize= MAX_PATH;
dllname.resize(dllnamesize);
rc= RegQueryValueEx(hKeyAP, 0, 0, 0, (BYTE*)&dllname[0], &dllnamesize);
RegCloseKey(hKeyAP);
if (rc==0) {
dllname.resize(strlen(dllname.c_str()));
if (dllname[dllname.size()-1]!='\\' && dllname[dllname.size()-1]!='/')
dllname += "\\";
dllname += "bin\\";
dllname += name;
if (PathFileExists(dllname.c_str()))
return true;
}
}
return false;
}
bool search_activestate_regkeys(const std::string& name, std::string& dllname)
{
HKEY hKey;
LONG rc;
rc= RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Activestate\\ActivePerl", 0, KEY_READ, &hKey);
if (rc)
return false;
char apversion[256];
for (int i=0 ; 1 ; i++) {
DWORD namelen= 256;
rc= RegEnumKeyEx(hKey, i, apversion, &namelen, 0, 0, 0, 0);
if (rc==ERROR_NO_MORE_ITEMS)
break;
if (search_regkey(hKey, apversion, name, dllname))
return true;
}
return false;
}
bool search_perl_regkey(const std::string& name, std::string& dllname)
{
return search_regkey(HKEY_LOCAL_MACHINE, "Software\\Perl", name, dllname);
}
bool search_perl_directories(const std::string& name, std::string& dllname)
{
// todo - try c:\perl*\bin\<dllname>
return false;
}
bool searchperldll(const std::string& name, std::string& dllname)
{
// HKLM\software\activestate\ActivePerl\*
return search_activestate_regkeys(name, dllname)
// HKLM\software\perl
|| search_perl_regkey(name, dllname)
// c:\perl*
|| search_perl_directories(name, dllname);
}
bool PerlDll::load()
{
tracemsg("PerlDll::load\n");
std::string dllname;
if (!searchperldll(DYNAMIC_PERL_DLL, dllname)) {
// try loading it from the searchpath
dllname= DYNAMIC_PERL_DLL;
}
msg("loading %s\n", dllname.c_str());
_h= LoadLibrary(dllname.c_str());
if (_h==NULL || _h==INVALID_HANDLE_VALUE) {
msg("IDAPERL ERROR: LoadLibrary %s\n", dllname.c_str());
return false;
}
if (!load_procs()) {
unload();
return false;
}
int argc=0;
char **argv=NULL;
char **env=NULL;
PERL_SYS_INIT3(&argc,&argv,&env);
tracemsg("PerlDll::load done\n");
return true;
}