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
// Hand-written Custom bodies for the generated meta domain (namespace gen): database-wide
// metadata, bitness, image base, and four identity strings (processor, file-type text, input
// path, root filename). String getters throw std::runtime_error (a Rust Err) when the SDK
// reports no value.
#include <ida.hpp>
#include <pro.h>
#include <loader.hpp>
#include <nalt.hpp>
#include <stdexcept>
#include "gen_meta.h"
namespace gen {
// Address bitness of the database: 16, 32, or 64.
int32_t bitness() { return static_cast<int32_t>(inf_get_app_bitness()); }
// Base address the input file was loaded at.
uint64_t image_base() { return static_cast<uint64_t>(get_imagebase()); }
// Name of the processor module the database was analyzed with; throws when it is unset.
rust::String proc_name() {
qstring out = inf_get_procname();
if (out.length() == 0)
throw std::runtime_error("no processor name");
return to_rust_string(out);
}
// No SDK constant bounds a processor's file-type text; comfortably above any real name.
constexpr size_t FILE_TYPE_NAME_BUF_SIZE = 256;
// Human-readable file type (e.g. "Portable executable"); throws when the SDK reports none.
rust::String file_type_name() {
char buf[FILE_TYPE_NAME_BUF_SIZE];
size_t n = get_file_type_name(buf, sizeof(buf));
if (n == 0)
throw std::runtime_error("no file type name");
// "size of answer" is IDA's phrasing for the full source length, not the copied count.
size_t len = n < sizeof(buf) ? n : sizeof(buf);
return to_rust_string(buf, len);
}
// Full path to the original input file; throws when the database has none recorded.
rust::String input_path() {
// get_input_file_path goes through getinf_buf, whose count includes the trailing NUL.
char buf[QMAXPATH];
ssize_t n = get_input_file_path(buf, sizeof(buf));
if (n <= 0)
throw std::runtime_error("no input file path");
return to_rust_string(buf, static_cast<size_t>(n - 1));
}
// Base filename (no directory) of the input file; throws when the database has none recorded.
rust::String root_filename() {
// get_root_filename's header never promises the count is what it stored, so clamp it.
char buf[QMAXPATH];
ssize_t n = get_root_filename(buf, sizeof(buf));
if (n <= 0)
throw std::runtime_error("no root filename");
size_t len = static_cast<size_t>(n) < sizeof(buf) ? static_cast<size_t>(n) : sizeof(buf);
return to_rust_string(buf, len);
}
} // namespace gen