-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathperl_magic.cpp
executable file
·97 lines (89 loc) · 2.6 KB
/
perl_magic.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
/* vim:set ts=4 sw=4:
*
* (C) 2008 Willem Hengeveld [email protected]
*
* IdcPerl - a perl scripting plugin for the Interactive Disassembler by hex-rays.
* see http://www.xs4all.nl/~itsme/projects/idcperl
*
* this file contains code handling magic 'uvar's
* that is a perl scalar with a 'set' and 'get' function.
*
* currently that is just '$here'
*/
// perl includes
#include "extern.h"
#include "perl.h"
#include "xsub.h"
#undef do_open
#undef do_close
#ifdef DYNAMIC_PERL
#include "redefperlasdll.h"
#include "perldllprocs.h"
#endif
#include "perl_magic.h"
// work around namespace collisions
#undef unpack_str
// ida includes
#include "pro.h" // for uchar
#include "kernwin.hpp" // for msg()
#ifdef TRACE_MAGIC
#define tracemsg msg
#else
#define tracemsg(...)
#endif
// do i need to pass pTHX here, for the current interpreter?
// NO: it is handled implicitly by the sv_setiv macro, which calls 'Perl_get_context()'
struct magichandler {
virtual ~magichandler() { }
virtual const char* name() const=0;
virtual bool readonly() const=0;
virtual void getter(SV *) const=0;
virtual void setter(SV *)=0;
};
struct here_handler : magichandler {
virtual const char* name() const { return "main::here"; }
virtual bool readonly() const { return false; }
virtual void getter(SV *sv) const { sv_setiv(sv, get_screen_ea()); }
virtual void setter(SV *sv) { jumpto(SvIV(sv),0); }
};
struct magichandler* magicitems[]={
new here_handler(),
};
#define NMAGICITEMS (sizeof(magicitems)/sizeof(*magicitems))
I32 get_magic(pTHX_ IV iv, SV *sv)
{
PERL_SET_CONTEXT(my_perl);
if (iv < 0 || unsigned(iv) >= NMAGICITEMS) {
msg("IDAPERL ERROR: unknown magic id: %ld\n", iv);
return 0;
}
magicitems[iv]->getter(sv);
return 0;
}
I32 set_magic(pTHX_ IV iv, SV *sv)
{
PERL_SET_CONTEXT(my_perl);
if (iv < 0 || unsigned(iv) >= NMAGICITEMS) {
msg("IDAPERL ERROR: unknown magic id: %ld\n", iv);
return 0;
}
if (!magicitems[iv]->readonly())
magicitems[iv]->setter(sv);
return 0;
}
void register_magic(pTHX)
{
PERL_SET_CONTEXT(my_perl);
tracemsg("register_magic\n");
SV *sv;
for (unsigned i=0 ; i<NMAGICITEMS ; i++) {
sv = perl_get_sv(magicitems[i]->name(), TRUE);
struct ufuncs uf;
uf.uf_val= get_magic;
uf.uf_set= set_magic;
uf.uf_index= i;
sv_magic(sv, NULL, PERL_MAGIC_uvar, (char *)&uf, sizeof(uf));
if (magicitems[i]->readonly())
SvREADONLY_on(sv);
}
}