Skip to content

Commit f3e00f1

Browse files
committed
Added __repr__ magic functions for helpers and updated jupyter notebook
1 parent 58b266e commit f3e00f1

File tree

3 files changed

+138
-12
lines changed

3 files changed

+138
-12
lines changed

examples/jupyter_tutorial.ipynb

Lines changed: 122 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,85 @@
7171
"metadata": {},
7272
"outputs": [],
7373
"source": [
74-
"conn = inventory.connector(\"kvm\", \":win11:\")\n"
74+
"connector = inventory.create_connector(name=\"kvm\", args=\":win11:\")"
75+
]
76+
},
77+
{
78+
"attachments": {},
79+
"cell_type": "markdown",
80+
"id": "bb246aa8",
81+
"metadata": {},
82+
"source": [
83+
"Without the `target` argument the kvm connector will just pick the first virtual machine it finds. It is also possible on some connectors to retrieve a list of all available targets (whereas the resulting `name` is the name of the target):"
84+
]
85+
},
86+
{
87+
"cell_type": "code",
88+
"execution_count": null,
89+
"id": "760b6687",
90+
"metadata": {},
91+
"outputs": [],
92+
"source": [
93+
"inventory.connector_target_list(\"qemu\")"
94+
]
95+
},
96+
{
97+
"attachments": {},
98+
"cell_type": "markdown",
99+
"id": "150e13f0",
100+
"metadata": {},
101+
"source": [
102+
"It is also possible to retrieve a Help-Text for Plugins, this is especially useful when writing CLI applications:"
103+
]
104+
},
105+
{
106+
"cell_type": "code",
107+
"execution_count": 19,
108+
"id": "7c2d9f98",
109+
"metadata": {},
110+
"outputs": [
111+
{
112+
"data": {
113+
"text/plain": [
114+
"'The `qemu` connector implements a memflow plugin interface\\nfor QEMU on top of the Process Filesystem on Linux.\\n\\nThis connector requires access to the qemu process via the linux procfs.\\nThis means any process which loads this connector requires\\nto have at least ptrace permissions set.\\n\\nThe `target` argument specifies the target qemu virtual machine.\\nThe qemu virtual machine name can be specified when starting qemu with the -name flag.\\n\\nAvailable arguments are:\\nmap_base: override of VM memory base\\nmap_size: override of VM memory size'"
115+
]
116+
},
117+
"execution_count": 19,
118+
"metadata": {},
119+
"output_type": "execute_result"
120+
}
121+
],
122+
"source": [
123+
"inventory.connector_help(\"qemu\")"
124+
]
125+
},
126+
{
127+
"cell_type": "code",
128+
"execution_count": 20,
129+
"id": "e7f09308",
130+
"metadata": {},
131+
"outputs": [
132+
{
133+
"name": "stderr",
134+
"output_type": "stream",
135+
"text": [
136+
"ERROR memflow.error 2022-12-18 21:00:09,824 error.rs:31 connector: not supported (Os-Plugin `win32` does not support help text.)\n"
137+
]
138+
},
139+
{
140+
"ename": "Exception",
141+
"evalue": "connector: not supported",
142+
"output_type": "error",
143+
"traceback": [
144+
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
145+
"\u001b[0;31mException\u001b[0m Traceback (most recent call last)",
146+
"Cell \u001b[0;32mIn[20], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m inventory\u001b[39m.\u001b[39;49mos_help(\u001b[39m\"\u001b[39;49m\u001b[39mwin32\u001b[39;49m\u001b[39m\"\u001b[39;49m)\n",
147+
"\u001b[0;31mException\u001b[0m: connector: not supported"
148+
]
149+
}
150+
],
151+
"source": [
152+
"inventory.os_help(\"win32\")"
75153
]
76154
},
77155
{
@@ -80,7 +158,7 @@
80158
"id": "2c510e26",
81159
"metadata": {},
82160
"source": [
83-
"The next step is to utilize the previously created connector to initialize an OS. In the given example we try to find Windows running in memory. "
161+
"The previously created connector can now be utilized to initialize an Os. In the given example we try to find Windows running in memory in the KVM Virtual Machine."
84162
]
85163
},
86164
{
@@ -90,7 +168,7 @@
90168
"metadata": {},
91169
"outputs": [],
92170
"source": [
93-
"os = inventory.os(\"win32\", conn)"
171+
"os = inventory.create_os(name=\"win32\", input=connector)"
94172
]
95173
},
96174
{
@@ -112,8 +190,17 @@
112190
"from pprint import pprint\n",
113191
"\n",
114192
"drivers = os.module_info_list()\n",
115-
"for driver in drivers: # TODO: implement str for module list\n",
116-
" pprint(driver.name)"
193+
"pprint(drivers)"
194+
]
195+
},
196+
{
197+
"cell_type": "code",
198+
"execution_count": null,
199+
"id": "88aa478d-d24c-46d0-b419-3310663834fd",
200+
"metadata": {},
201+
"outputs": [],
202+
"source": [
203+
"kernel = os # TODO:"
117204
]
118205
},
119206
{
@@ -128,14 +215,22 @@
128215
{
129216
"cell_type": "code",
130217
"execution_count": null,
131-
"id": "88aa478d-d24c-46d0-b419-3310663834fd",
218+
"id": "0dc364fa",
132219
"metadata": {},
133220
"outputs": [],
134221
"source": [
135-
"kernel = os # TODO:\n",
136222
"process = os.process_from_name(\"explorer.exe\")"
137223
]
138224
},
225+
{
226+
"attachments": {},
227+
"cell_type": "markdown",
228+
"id": "d0ef57bf",
229+
"metadata": {},
230+
"source": [
231+
"A Process also features the same functions for retrieving modules:"
232+
]
233+
},
139234
{
140235
"cell_type": "code",
141236
"execution_count": null,
@@ -145,10 +240,17 @@
145240
"source": [
146241
"from pprint import pprint\n",
147242
"\n",
148-
"# List all modules in the process:\n",
149243
"modules = process.module_info_list()\n",
150-
"for mod in modules: # TODO: implement str for module list\n",
151-
" pprint(mod.name)"
244+
"pprint(modules)"
245+
]
246+
},
247+
{
248+
"attachments": {},
249+
"cell_type": "markdown",
250+
"id": "9194330f",
251+
"metadata": {},
252+
"source": [
253+
"It is also possible to get a module by it's name:"
152254
]
153255
},
154256
{
@@ -158,10 +260,18 @@
158260
"metadata": {},
159261
"outputs": [],
160262
"source": [
161-
"# Load module 'Explorer.EXE':\n",
162263
"module = process.module_from_name(\"Explorer.EXE\")"
163264
]
164265
},
266+
{
267+
"attachments": {},
268+
"cell_type": "markdown",
269+
"id": "b612a8d1",
270+
"metadata": {},
271+
"source": [
272+
"Finally we are able to read Data from the process/module. In the following example we read parts of the COFF Header from the PE Header of the primary module:"
273+
]
274+
},
165275
{
166276
"cell_type": "code",
167277
"execution_count": null,
@@ -187,7 +297,7 @@
187297
],
188298
"metadata": {
189299
"kernelspec": {
190-
"display_name": "Python 3",
300+
"display_name": "Python 3 (ipykernel)",
191301
"language": "python",
192302
"name": "python3"
193303
},

src/inventory.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,10 @@ impl PyTargetInfo {
165165
fn __str__(&self) -> String {
166166
format!("{:?}", self.0)
167167
}
168+
169+
fn __repr__(&self) -> String {
170+
format!("{:?}", self.0)
171+
}
168172
}
169173

170174
impl From<TargetInfo> for PyTargetInfo {

src/process.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ impl PyProcess {
7171
fn __str__(&self) -> String {
7272
format!("{:?}", self.0.info())
7373
}
74+
75+
fn __repr__(&self) -> String {
76+
format!("{:?}", self.0.info())
77+
}
7478
}
7579

7680
#[derive(Clone)]
@@ -97,6 +101,10 @@ impl PyProcessInfo {
97101
fn __str__(&self) -> String {
98102
format!("{:?}", self.0)
99103
}
104+
105+
fn __repr__(&self) -> String {
106+
format!("{:?}", self.0)
107+
}
100108
}
101109

102110
impl From<ProcessInfo> for PyProcessInfo {
@@ -145,6 +153,10 @@ impl PyModuleInfo {
145153
fn __str__(&self) -> String {
146154
format!("{:?}", self.0)
147155
}
156+
157+
fn __repr__(&self) -> String {
158+
format!("{:?}", self.0)
159+
}
148160
}
149161

150162
impl From<ModuleInfo> for PyModuleInfo {

0 commit comments

Comments
 (0)