Rizin
unix-like reverse engineering framework and cli tools
pdb_downloader.c File Reference
#include <string.h>
#include <rz_util.h>
#include <rz_core.h>
#include <rz_windows.h>
#include <rz_socket.h>
#include "pdb_downloader.h"

Go to the source code of this file.

Functions

static bool download_and_write (SPDBDownloaderOpt *opt, const char *file)
 
static char * download (struct SPDBDownloader *pd)
 
void init_pdb_downloader (SPDBDownloaderOpt *opt, SPDBDownloader *pd)
 initialization of pdb downloader by SPDBDownloaderOpt More...
 
void deinit_pdb_downloader (SPDBDownloader *pd)
 deinitialization of PDB downloader More...
 
static bool is_valid_guid (const char *guid)
 
RZ_API int rz_bin_pdb_download (RZ_NONNULL RzBin *bin, RZ_NULLABLE PJ *pj, int isradjson, RZ_NONNULL SPDBOptions *options)
 Download PDB file for currently opened RzBin file. More...
 
RZ_API RZ_OWN char * rz_bin_symserver_download (RZ_NONNULL const SPDBDownloaderOpt *options)
 downloads file from symbol server More...
 

Function Documentation

◆ deinit_pdb_downloader()

void deinit_pdb_downloader ( SPDBDownloader pd)

deinitialization of PDB downloader

Parameters
pdb_downloaderPDB downloader that will be deinitialized

Definition at line 142 of file pdb_downloader.c.

142  {
143  RZ_FREE(pd->opt->dbg_file);
144  RZ_FREE(pd->opt->guid);
145  RZ_FREE(pd->opt->symbol_server);
147  RZ_FREE(pd->opt);
148  pd->download = 0;
149 }
#define RZ_FREE(x)
Definition: rz_types.h:369
const char * dbg_file
const char * symbol_server
const char * symbol_store_path
const char * guid
SPDBDownloaderOpt * opt
char *(* download)(struct SPDBDownloader *pdb_downloader)

References SPDBDownloaderOpt::dbg_file, SPDBDownloader::download, SPDBDownloaderOpt::guid, SPDBDownloader::opt, RZ_FREE, SPDBDownloaderOpt::symbol_server, and SPDBDownloaderOpt::symbol_store_path.

Referenced by rz_bin_symserver_download().

◆ download()

static char* download ( struct SPDBDownloader pd)
static

Definition at line 59 of file pdb_downloader.c.

59  {
60  SPDBDownloaderOpt *opt = pd->opt;
61  bool downloaded = false;
62 
63  if (!opt->dbg_file || !*opt->dbg_file) {
64  // no pdb debug file
65  return NULL;
66  }
67 
68  char *abspath_to_file = rz_str_newf("%s%s%s%s%s%s%s",
70  opt->dbg_file, RZ_SYS_DIR,
71  opt->guid, RZ_SYS_DIR,
72  opt->dbg_file);
73 
74  if (rz_file_exists(abspath_to_file)) {
75  eprintf("File already downloaded.\n");
76  return abspath_to_file;
77  }
78 
79  if (opt->extract == 0) {
80  char *extractor_cmd = NULL;
81  char *archive_name = strdup(opt->dbg_file);
82  archive_name[strlen(archive_name) - 1] = '_';
83  char *abspath_to_archive = rz_str_newf("%s%s%s%s%s%s%s",
85  opt->dbg_file, RZ_SYS_DIR,
86  opt->guid, RZ_SYS_DIR,
87  archive_name);
88  char *abspath_to_dir = rz_file_dirname(abspath_to_archive);
89 
90  eprintf("Attempting to download compressed pdb in %s\n", abspath_to_archive);
91  downloaded = download_and_write(opt, archive_name);
92 
93  if (opt->extract > 0 && downloaded) {
94  eprintf("Attempting to decompress pdb\n");
95  if (!rz_bin_pdb_extract_in_folder(abspath_to_archive, abspath_to_dir)) {
96  downloaded = false;
97  }
98  rz_file_rm(abspath_to_archive);
99  }
100  free(archive_name);
101  free(abspath_to_dir);
102  free(abspath_to_archive);
103  free(extractor_cmd);
104  }
105  if (!downloaded) {
106  eprintf("Falling back to uncompressed pdb\n");
107  eprintf("Attempting to download uncompressed pdb in %s\n", abspath_to_file);
108  downloaded = download_and_write(opt, opt->dbg_file);
109  if (!downloaded) {
110  RZ_FREE(abspath_to_file);
111  }
112  }
113  return downloaded ? abspath_to_file : NULL;
114 }
RZ_API bool rz_bin_pdb_extract_in_folder(RZ_NONNULL const char *file_cab, RZ_NONNULL const char *output_dir)
Extracts compressed PDB files into a folder.
Definition: cab_extract.c:209
#define NULL
Definition: cris-opc.c:27
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
static bool download_and_write(SPDBDownloaderOpt *opt, const char *file)
#define eprintf(x, y...)
Definition: rlcc.c:7
RZ_API bool rz_file_exists(const char *str)
Definition: file.c:192
RZ_API char * rz_file_dirname(const char *path)
Definition: file.c:120
RZ_API bool rz_file_rm(const char *file)
Definition: file.c:865
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
#define RZ_SYS_DIR
Definition: rz_types.h:218

References SPDBDownloaderOpt::dbg_file, download_and_write(), eprintf, SPDBDownloaderOpt::extract, free(), SPDBDownloaderOpt::guid, NULL, SPDBDownloader::opt, rz_bin_pdb_extract_in_folder(), rz_file_dirname(), rz_file_exists(), rz_file_rm(), RZ_FREE, rz_str_newf(), RZ_SYS_DIR, strdup(), and SPDBDownloaderOpt::symbol_store_path.

Referenced by init_pdb_downloader().

◆ download_and_write()

static bool download_and_write ( SPDBDownloaderOpt opt,
const char *  file 
)
static

Definition at line 11 of file pdb_downloader.c.

11  {
12  char *dir = rz_str_newf("%s%s%s%s%s",
14  opt->dbg_file, RZ_SYS_DIR,
15  opt->guid);
16  if (!rz_sys_mkdirp(dir)) {
17  free(dir);
18  return false;
19  }
20  char *path = rz_str_newf("%s%s%s", dir, RZ_SYS_DIR, opt->dbg_file);
21  if (rz_file_exists(path)) {
22  free(dir);
23  free(path);
24  return true;
25  }
26  char *url = rz_str_newf("%s/%s/%s/%s", opt->symbol_server, opt->dbg_file, opt->guid, file);
27 #if __WINDOWS__
28  if (rz_str_startswith(url, "\\\\")) { // Network path
29  wchar_t *origin = rz_utf8_to_utf16(url);
30  wchar_t *dest = rz_utf8_to_utf16(path);
31  BOOL ret = CopyFileW(origin, dest, FALSE);
32  free(dir);
33  free(path);
34  free(origin);
35  free(dest);
36  return ret;
37  }
38 #endif
39  int len;
40  char *file_buf = rz_socket_http_get(url, NULL, &len);
41  free(url);
42  if (!len || RZ_STR_ISEMPTY(file_buf)) {
43  free(dir);
44  free(file_buf);
45  free(path);
46  return false;
47  }
48  FILE *f = fopen(path, "wb");
49  if (f) {
50  fwrite(file_buf, sizeof(char), (size_t)len, f);
51  fclose(f);
52  }
53  free(dir);
54  free(path);
55  free(file_buf);
56  return true;
57 }
size_t len
Definition: 6502dis.c:15
static static fork const void static count static fd const char const char static newpath const char static path const char path
Definition: sflib.h:35
voidpf uLong int origin
Definition: ioapi.h:144
char * dest
Definition: lz4.h:697
#define FALSE
Definition: mybfd.h:102
string FILE
Definition: benchmark.py:21
url
Definition: setup.py:262
RZ_API char * rz_socket_http_get(const char *url, int *code, int *rlen)
Definition: socket_http.c:287
#define RZ_STR_ISEMPTY(x)
Definition: rz_str.h:67
RZ_API bool rz_str_startswith(RZ_NONNULL const char *str, RZ_NONNULL const char *needle)
Checks if a string starts with a specifc sequence of characters (case sensitive)
Definition: str.c:3286
RZ_API bool rz_sys_mkdirp(const char *dir)
Definition: sys.c:691
#define f(i)
Definition: sha256.c:46
Definition: gzappend.c:170

References SPDBDownloaderOpt::dbg_file, dest, f, FALSE, benchmark::FILE, free(), SPDBDownloaderOpt::guid, len, NULL, path, rz_file_exists(), rz_socket_http_get(), RZ_STR_ISEMPTY, rz_str_newf(), rz_str_startswith(), RZ_SYS_DIR, rz_sys_mkdirp(), SPDBDownloaderOpt::symbol_server, SPDBDownloaderOpt::symbol_store_path, and setup::url.

Referenced by download().

◆ init_pdb_downloader()

void init_pdb_downloader ( SPDBDownloaderOpt opt,
SPDBDownloader pd 
)

initialization of pdb downloader by SPDBDownloaderOpt

Parameters
optPDB options
pdb_downloaderPDB downloader that will be initialized

Definition at line 122 of file pdb_downloader.c.

122  {
124  if (!pd->opt) {
125  pd->download = 0;
126  eprintf("Cannot allocate memory for SPDBDownloaderOpt.\n");
127  return;
128  }
129  pd->opt->dbg_file = strdup(opt->dbg_file);
130  pd->opt->guid = strdup(opt->guid);
131  pd->opt->symbol_server = strdup(opt->symbol_server);
133  pd->opt->extract = opt->extract;
134  pd->download = download;
135 }
static char * download(struct SPDBDownloader *pd)
#define RZ_NEW0(x)
Definition: rz_types.h:284

References SPDBDownloaderOpt::dbg_file, download(), SPDBDownloader::download, eprintf, SPDBDownloaderOpt::extract, SPDBDownloaderOpt::guid, SPDBDownloader::opt, RZ_NEW0, strdup(), SPDBDownloaderOpt::symbol_server, and SPDBDownloaderOpt::symbol_store_path.

Referenced by rz_bin_symserver_download().

◆ is_valid_guid()

static bool is_valid_guid ( const char *  guid)
static

Definition at line 151 of file pdb_downloader.c.

151  {
152  if (!guid) {
153  return false;
154  }
155  size_t i;
156  for (i = 0; guid[i]; i++) {
157  if (!isxdigit(guid[i])) {
158  return false;
159  }
160  }
161  return i >= 33; // len of GUID and age
162 }
lzma_index ** i
Definition: index.h:629
#define isxdigit(c)
Definition: safe-ctype.h:145

References i, and isxdigit.

Referenced by rz_bin_pdb_download().

◆ rz_bin_pdb_download()

RZ_API int rz_bin_pdb_download ( RZ_NONNULL RzBin bin,
RZ_NULLABLE PJ pj,
int  isradjson,
RZ_NONNULL SPDBOptions options 
)

Download PDB file for currently opened RzBin file.

Parameters
binRzBin instance
pjOptional PJ instance for json output
isradjsonUse pj for json output
optionssymbol server options for downloading the PDB file

Definition at line 171 of file pdb_downloader.c.

171  {
173  SPDBDownloaderOpt opt;
175 
176  if (!info || !info->debug_file_name) {
177  RZ_LOG_ERROR("Can't find debug filename\n");
178  return 1;
179  }
180 
181  if (!is_valid_guid(info->guid)) {
182  RZ_LOG_ERROR("Invalid GUID for file\n");
183  return 1;
184  }
185 
186  if (!options->symbol_server || !options->symbol_store_path) {
187  RZ_LOG_ERROR("Can't retrieve pdb configurations\n");
188  return 1;
189  }
190 
192  opt.guid = info->guid;
193  opt.symbol_server = options->symbol_server;
194  opt.symbol_store_path = options->symbol_store_path;
195  opt.extract = options->extract;
196 
197  char *path = rz_bin_symserver_download(&opt);
198 
199  if (isradjson) {
200  pj_ko(pj, "pdb");
201  pj_ks(pj, "file", opt.dbg_file);
202  pj_ks(pj, "guid", opt.guid);
203  pj_ks(pj, "path", path);
204  pj_kb(pj, "download", (bool)path);
205  pj_end(pj);
206  } else {
207  rz_cons_printf("PDB \"%s\" download %s\n",
208  opt.dbg_file, path ? "success" : "failed");
209  }
210  free(path);
211  return !path;
212 }
RZ_DEPRECATE RZ_API RZ_BORROW RzBinInfo * rz_bin_get_info(RzBin *bin)
Definition: bin.c:585
RzBinInfo * info(RzBinFile *bf)
Definition: bin_ne.c:86
RZ_API int rz_cons_printf(const char *format,...)
Definition: cons.c:1202
static const char struct stat static buf struct stat static buf static vhangup int options
Definition: sflib.h:145
RZ_API RZ_OWN char * rz_bin_symserver_download(RZ_NONNULL const SPDBDownloaderOpt *options)
downloads file from symbol server
static bool is_valid_guid(const char *guid)
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
RZ_API const char * rz_file_dos_basename(RZ_BORROW RZ_NONNULL const char *path)
Definition: file.c:102
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
RZ_API PJ * pj_ko(PJ *j, const char *k)
Definition: pj.c:156
RZ_API PJ * pj_kb(PJ *j, const char *k, bool v)
Definition: pj.c:177
RZ_API PJ * pj_end(PJ *j)
Definition: pj.c:87
RZ_API PJ * pj_ks(PJ *j, const char *k, const char *v)
Definition: pj.c:170
Definition: malloc.c:26
char * guid
Definition: rz_bin.h:222
char * debug_file_name
Definition: rz_bin.h:223

References SPDBDownloaderOpt::dbg_file, rz_bin_info_t::debug_file_name, SPDBDownloaderOpt::extract, free(), SPDBDownloaderOpt::guid, rz_bin_info_t::guid, info(), is_valid_guid(), options, path, pj_end(), pj_kb(), pj_ko(), pj_ks(), rz_bin_get_info(), rz_bin_symserver_download(), rz_cons_printf(), rz_file_dos_basename(), RZ_LOG_ERROR, rz_return_val_if_fail, SPDBDownloaderOpt::symbol_server, and SPDBDownloaderOpt::symbol_store_path.

Referenced by download_pdb(), GetHeapGlobalsOffset(), rz_cmd_info_pdb_download_handler(), and rz_main_rz_bin().

◆ rz_bin_symserver_download()

RZ_API RZ_OWN char* rz_bin_symserver_download ( RZ_NONNULL const SPDBDownloaderOpt options)

downloads file from symbol server

Parameters
optionsoptions for downloading file
Returns
char* is the path that file was downloaded to or NULL in case of failure

Definition at line 219 of file pdb_downloader.c.

219  {
221  SPDBDownloader downloader;
222  SPDBDownloaderOpt opt = *options;
223  char *path = NULL;
224  char *symbol_server = strdup(options->symbol_server);
225  char *server = strtok(symbol_server, ";");
226  while (server && !path) {
227  opt.symbol_server = server;
228  init_pdb_downloader(&opt, &downloader);
229  if (!downloader.download) {
230  break;
231  }
232  path = downloader.download(&downloader);
233  deinit_pdb_downloader(&downloader);
234  server = strtok(NULL, ";");
235  }
236  free(symbol_server);
237  return path;
238 }
void deinit_pdb_downloader(SPDBDownloader *pd)
deinitialization of PDB downloader
void init_pdb_downloader(SPDBDownloaderOpt *opt, SPDBDownloader *pd)
initialization of pdb downloader by SPDBDownloaderOpt

References deinit_pdb_downloader(), SPDBDownloader::download, free(), init_pdb_downloader(), NULL, options, path, rz_return_val_if_fail, strdup(), and SPDBDownloaderOpt::symbol_server.

Referenced by rz_bin_pdb_download(), and winkd_download_module_and_pdb().