Skip to content
This repository was archived by the owner on Dec 24, 2025. It is now read-only.

Commit 930d7cb

Browse files
author
elias.bachaalany@gmail.com
committed
added PyWraps sources. This will facilitate deployment, development and debugging of IDAPython additions
1 parent 1258fab commit 930d7cb

69 files changed

Lines changed: 24434 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

pywraps/deploy.bat

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
@echo off
2+
3+
rem Please use the same tag for the same .i file
4+
rem That means if many insertions are going to happen in one given .i file then don't use more than code marking tag
5+
6+
set PY=c:\python26\python.exe
7+
8+
echo.
9+
echo -------- DEPLOY started --------------------------------------------------
10+
echo.
11+
12+
rem --------------------------------------------------------------------------
13+
echo Deploying idaapi (common functions, notifywhen)
14+
%PY% deploy.py py_idaapi py_cvt.hpp,py_idaapi.hpp,py_idaapi.py,py_notifywhen.hpp,py_notifywhen.py ..\swig\idaapi.i
15+
16+
rem --------------------------------------------------------------------------
17+
echo Deploying Graph
18+
%PY% deploy.py py_graph py_graph.hpp,py_graph.py ..\swig\graph.i
19+
20+
rem --------------------------------------------------------------------------
21+
echo Deploying custview
22+
%PY% deploy.py py_custviewer py_custview.py,py_custview.hpp ..\swig\kernwin.i
23+
24+
rem --------------------------------------------------------------------------
25+
echo Deploying plgform
26+
%PY% deploy.py py_plgform py_plgform.hpp,py_plgform.py ..\swig\kernwin.i
27+
28+
rem --------------------------------------------------------------------------
29+
echo Deploying expr
30+
%PY% deploy.py py_expr py_expr.hpp,py_expr.py ..\swig\expr.i
31+
32+
rem --------------------------------------------------------------------------
33+
echo Deploying cli
34+
%PY% deploy.py py_cli py_cli.py,py_cli.hpp ..\swig\kernwin.i
35+
36+
rem --------------------------------------------------------------------------
37+
echo Deploying Loader
38+
%PY% deploy.py py_loader py_loader.hpp ..\swig\loader.i
39+
40+
rem --------------------------------------------------------------------------
41+
echo Deploying kernwin, choose2, askusingform
42+
%PY% deploy.py py_kernwin py_kernwin.hpp,py_kernwin.py,py_choose.hpp,py_choose2.hpp,py_choose2.py,py_askusingform.hpp,py_askusingform.py ..\swig\kernwin.i
43+
44+
rem --------------------------------------------------------------------------
45+
echo Deploying idd
46+
%PY% deploy.py py_idd py_dbg.hpp,py_appcall.py ..\swig\idd.i
47+
48+
rem --------------------------------------------------------------------------
49+
echo Deploying nalt
50+
%PY% deploy.py py_nalt py_nalt.hpp,py_nalt.py ..\swig\nalt.i
51+
52+
rem --------------------------------------------------------------------------
53+
echo Deploying dbg
54+
%PY% deploy.py py_dbg py_dbg.hpp ..\swig\dbg.i
55+
56+
rem --------------------------------------------------------------------------
57+
echo Deploying linput/diskio
58+
%PY% deploy.py py_diskio py_linput.hpp,py_diskio.hpp,py_diskio.py ..\swig\diskio.i
59+
60+
rem --------------------------------------------------------------------------
61+
echo Deploying name
62+
%PY% deploy.py py_name py_name.hpp,py_name.py ..\swig\name.i
63+
64+
rem --------------------------------------------------------------------------
65+
echo Deploying qfile
66+
%PY% deploy.py py_qfile py_qfile.hpp ..\swig\fpro.i
67+
68+
rem --------------------------------------------------------------------------
69+
echo Deploying bytes
70+
%PY% deploy.py py_bytes py_bytes.hpp,py_custdata.py,py_custdata.hpp ..\swig\bytes.i
71+
72+
rem --------------------------------------------------------------------------
73+
echo Deploying typeinf
74+
%PY% deploy.py py_typeinf py_typeinf.hpp ..\swig\typeinf.i
75+
76+
rem --------------------------------------------------------------------------
77+
echo Deploying gdl
78+
%PY% deploy.py py_gdl py_gdl.py ..\swig\gdl.i
79+
80+
rem --------------------------------------------------------------------------
81+
echo Deploying ua
82+
%PY% deploy.py py_ua py_ua.hpp,py_ua.py ..\swig\ua.i
83+
84+
rem --------------------------------------------------------------------------
85+
echo Deploying idp
86+
%PY% deploy.py py_idp py_idp.hpp ..\swig\idp.i
87+
88+
rem --------------------------------------------------------------------------
89+
echo Deploying lines
90+
%PY% deploy.py py_lines py_lines.hpp,py_lines.py ..\swig\lines.i
91+
92+
rem --------------------------------------------------------------------------
93+
echo Deploying pc_win32_appcall
94+
%PY% deploy.py appcalltest py_appcall.py ..\..\..\ida\tests\input\pc_win32_appcall.pe.hints
95+
96+
rem --------------------------------------------------------------------------
97+
echo Deploying ex_custdata example
98+
%PY% deploy.py ex_custdata ..\examples\ex_custdata.py ..\..\..\ida\tests\input\pc_win32_custdata1.pe.hints
99+
100+
rem --------------------------------------------------------------------------
101+
echo Deploying ex_formchooser
102+
%PY% deploy.py ex_formchooser py_askusingform.py ..\..\formchooser\formchooser.py
103+
104+
rem --------------------------------------------------------------------------
105+
echo Deploying ex_askusingform
106+
%PY% deploy.py ex_askusingform py_askusingform.py ..\examples\ex_askusingform.py
107+
108+
rem --------------------------------------------------------------------------
109+
echo Deploying ex_cli example
110+
%PY% deploy.py ex_cli_ex1 py_cli.py ..\examples\ex_cli.py
111+
112+
rem --------------------------------------------------------------------------
113+
echo Deploying ex_expr example
114+
%PY% deploy.py ex_expr py_expr.py ..\examples\ex_expr.py
115+
116+
rem --------------------------------------------------------------------------
117+
echo Deploying ex_custview.py example
118+
%PY% deploy.py py_custviewerex1 py_custview.py ..\examples\ex_custview.py
119+
120+
rem --------------------------------------------------------------------------
121+
echo.
122+
echo -------- DEPLOY finished -------------------------------------------------
123+
echo.
124+
125+
:end

pywraps/deploy.py

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
"""
2+
Deploy code snips into swig interface files
3+
4+
(c) Hex-Rays
5+
"""
6+
7+
import sys
8+
import re
9+
import os
10+
11+
# creates a regular expression
12+
def make_re(tag, mod_name, prefix):
13+
s = '%(p)s<%(tag)s\(%(m)s\)>(.+?)%(p)s</%(tag)s\(%(m)s\)>' % {'m': mod_name, 'tag': tag, 'p': prefix}
14+
return (s, re.compile(s, re.DOTALL))
15+
16+
def deploy(mod_name, src_files, dest_file, silent = True):
17+
# create regular expressions
18+
templates = (
19+
('pycode', make_re('pycode', mod_name, '#')),
20+
('code', make_re('code', mod_name, '//')),
21+
('inline', make_re('inline', mod_name, '//'))
22+
)
23+
24+
if not os.path.exists(dest_file):
25+
print "File", dest_file, "does not exist and will be skipped"
26+
return
27+
28+
if not os.access(dest_file, os.W_OK):
29+
print "File", dest_file, "is not writable and will be skipped"
30+
return
31+
32+
# read dest file
33+
dest_lines = "".join(file(dest_file, "r").readlines())
34+
35+
# read all source files into one buffer
36+
src_lines = "".join(["".join(file(x, "r").readlines()) for x in src_files])
37+
38+
pcount = 0
39+
for desc, (expr_str, expr) in templates:
40+
# find source pattern
41+
matches = expr.findall(src_lines)
42+
if not matches:
43+
if not silent:
44+
print "Failed to match <%s> source expression against '%s', skipping...!" % (desc, expr_str)
45+
continue
46+
47+
# find pattern in destination
48+
dest = expr.search(dest_lines)
49+
if not dest:
50+
if not silent:
51+
print "Failed to match <%s> destination expression against '%s', skipping..." % (desc, expr_str)
52+
print dest_lines
53+
sys.exit(0)
54+
continue
55+
56+
# accumulate all the strings to be replaced
57+
replaces = []
58+
for src in matches:
59+
replaces.append(src)
60+
61+
dest_lines = dest_lines[:dest.start(1)] + "\n".join(replaces) + dest_lines[dest.end(1):]
62+
pcount += 1
63+
64+
65+
f = file(dest_file, 'w')
66+
if not f:
67+
print "Failed to open destination file:", dest_file
68+
return
69+
f.write(dest_lines)
70+
f.close()
71+
72+
if pcount:
73+
print "Deployed successfully: %s (%d)" % (dest_file, pcount)
74+
else:
75+
print "Nothing was deployed in: %s" % dest_file
76+
77+
78+
def main(argv = None):
79+
if not argv:
80+
argv = sys.argv
81+
if len(argv) != 4:
82+
print "Usage deploy.py modname src_file1,src_file2,... dest_file"
83+
return
84+
85+
mod_name = argv[1]
86+
src_files = argv[2].split(',')
87+
dest_file = argv[3]
88+
deploy(mod_name, src_files, dest_file)
89+
90+
#main(['', 'py_graph', 'py_graph.hpp,py_graph.py', 'graph.i'])
91+
main()

pywraps/driver.cpp

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
//--------------------------------------------------------------------------
2+
// IDA includes
3+
#include <windows.h>
4+
#include <pro.h>
5+
#include <ida.hpp>
6+
#include <idp.hpp>
7+
#include <loader.hpp>
8+
#include <bytes.hpp>
9+
#include <enum.hpp>
10+
#include <kernwin.hpp>
11+
#include <diskio.hpp>
12+
#include <bytes.hpp>
13+
#include <graph.hpp>
14+
#include <map>
15+
#include <idd.hpp>
16+
#include <dbg.hpp>
17+
#include <ieee.h>
18+
#include <err.h>
19+
#include <expr.hpp>
20+
#include <typeinf.hpp>
21+
#include <struct.hpp>
22+
#include <nalt.hpp>
23+
#include <frame.hpp>
24+
25+
//--------------------------------------------------------------------------
26+
// PyWraps
27+
#include <Python.h>
28+
#include "pywraps.hpp"
29+
#include "swig_stub.h"
30+
#include "py_cvt.hpp"
31+
#include "py_idaapi.hpp"
32+
#include "py_graph.hpp"
33+
#include "py_typeinf.hpp"
34+
#include "py_bytes.hpp"
35+
#include "py_linput.hpp"
36+
#include "py_qfile.hpp"
37+
#include "py_ua.hpp"
38+
#include "py_custdata.hpp"
39+
#include "py_notifywhen.hpp"
40+
#include "py_dbg.hpp"
41+
#include "py_choose2.hpp"
42+
#include "py_plgform.hpp"
43+
#include "py_cli.hpp"
44+
#include "py_custview.hpp"
45+
#include "py_lines.hpp"
46+
#include "py_nalt.hpp"
47+
#include "py_loader.hpp"
48+
#include "py_idp.hpp"
49+
#include "py_kernwin.hpp"
50+
#include "py_askusingform.hpp"
51+
#include "py_expr.hpp"
52+
53+
//--------------------------------------------------------------------------
54+
qvector<PyMethodDef> all_methods;
55+
void driver_add_methods(PyMethodDef *methods)
56+
{
57+
for ( ; methods->ml_name != NULL ; ++methods )
58+
all_methods.push_back(*methods);
59+
}
60+
61+
//--------------------------------------------------------------------------
62+
// Define a class and declare an instance so it gets executed on startup
63+
// It will add the desired methods to the all_methods global variable
64+
#define DRIVER_INIT_METHODS(name) \
65+
class init_##name##_driver_t \
66+
{ \
67+
public: \
68+
init_##name##_driver_t() \
69+
{ \
70+
driver_add_methods(py_methods_##name##); \
71+
} \
72+
} init_##name##_driver;
73+
74+
//--------------------------------------------------------------------------
75+
// PyWraps test drivers
76+
//#include "driver_kernwin.cpp"
77+
//#include "driver_chooser.cpp"
78+
#include "driver_expr.cpp"
79+
//#include "driver_custview.cpp"
80+
//#include "driver_notifywhen.cpp"
81+
//#include "driver_custdata.cpp"
82+
//#include "driver_graph.cpp"
83+
//#include "driver_diskio.cpp"
84+
//#include "driver_bytes.cpp"
85+
//#include "driver_dbg.cpp"
86+
//#include "driver_nalt.cpp"
87+
//#include "driver_cli.cpp"
88+
89+
//--------------------------------------------------------------------------
90+
//#define DRIVER_FIX
91+
92+
#ifdef DRIVER_FIX
93+
#define PLUGIN_FLAGS PLUGIN_FIX
94+
#else
95+
#define PLUGIN_FLAGS 0
96+
#endif
97+
98+
//--------------------------------------------------------------------------
99+
void setup_pywraps()
100+
{
101+
static bool installed = false;
102+
if ( installed )
103+
{
104+
msg("pywraps already installed\n");
105+
return;
106+
}
107+
static const PyMethodDef null_method = {0};
108+
all_methods.push_back(null_method);
109+
Py_InitModule("pywraps", all_methods.begin());
110+
init_pywraps();
111+
msg("pywraps installed!\n");
112+
installed = true;
113+
}
114+
115+
//--------------------------------------------------------------------------
116+
void idaapi run(int /*arg*/)
117+
{
118+
setup_pywraps();
119+
#ifdef DRIVER_RUN
120+
driver_run(0);
121+
#endif
122+
}
123+
124+
//--------------------------------------------------------------------------
125+
//
126+
// Initialize.
127+
//
128+
int idaapi init(void)
129+
{
130+
#ifndef DRIVER_FIX
131+
setup_pywraps();
132+
#endif
133+
#ifdef DRIVER_INIT
134+
return driver_init();
135+
#else
136+
return PLUGIN_KEEP;
137+
#endif
138+
}
139+
140+
//--------------------------------------------------------------------------
141+
void idaapi term(void)
142+
{
143+
#ifdef DRIVER_TERM
144+
driver_term();
145+
#endif
146+
}
147+
148+
//--------------------------------------------------------------------------
149+
//
150+
// PLUGIN DESCRIPTION BLOCK
151+
//
152+
//--------------------------------------------------------------------------
153+
plugin_t PLUGIN =
154+
{
155+
IDP_INTERFACE_VERSION,
156+
PLUGIN_FLAGS, // plugin flags
157+
init, // initialize
158+
159+
term, // terminate. this pointer may be NULL.
160+
161+
run, // invoke plugin
162+
163+
// long comment about the plugin
164+
"PyWraps plugin",
165+
166+
// it could appear in the status line
167+
// or as a hint
168+
"", // multiline help about the plugin
169+
170+
"pywraps", // the preferred short name of the plugin
171+
"Alt-0" // the preferred hotkey to run the plugin
172+
};

0 commit comments

Comments
 (0)