46 #ifdef __LP64__ // Generic 64b
47 #define Elf_Ehdr Elf64_Ehdr
48 #define Elf_Shdr Elf64_Shdr
49 #define Elf_Sym Elf64_Sym
50 #define Elf_Addr Elf64_Addr
51 #define Elf_Sword Elf64_Sxword
52 #define Elf_Section Elf64_Half
53 #define ELF_ST_BIND ELF64_ST_BIND
54 #define ELF_ST_TYPE ELF64_ST_TYPE
55 #define Elf_Rel Elf64_Rel
56 #define Elf_Rela Elf64_Rela
57 #define ELF_R_SYM ELF64_R_SYM
58 #define ELF_R_TYPE ELF64_R_TYPE
59 #define ELF_R_INFO ELF64_R_INFO
60 #define Elf_Phdr Elf64_Phdr
61 #define Elf_Xword Elf64_Xword
62 #define Elf_Word Elf64_Word
63 #define Elf_Off Elf64_Off
64 #define ELFCLASS ELFCLASS64
65 #define ELFMACHINE EM_X86_64
66 #define CS_MODE CS_MODE_64
67 #define RELOC_MODE RELOC_X86_64
69 #define Elf_Ehdr Elf32_Ehdr
70 #define Elf_Shdr Elf32_Shdr
71 #define Elf_Sym Elf32_Sym
72 #define Elf_Addr Elf32_Addr
73 #define Elf_Sword Elf64_Sword
74 #define Elf_Section Elf32_Half
75 #define ELF_ST_BIND ELF32_ST_BIND
76 #define ELF_ST_TYPE ELF32_ST_TYPE
77 #define Elf_Rel Elf32_Rel
78 #define Elf_Rela Elf32_Rela
79 #define ELF_R_SYM ELF32_R_SYM
80 #define ELF_R_TYPE ELF32_R_TYPE
81 #define ELF_R_INFO ELF32_R_INFO
82 #define Elf_Phdr Elf32_Phdr
83 #define Elf_Xword Elf32_Xword
84 #define Elf_Word Elf32_Word
85 #define Elf_Off Elf32_Off
86 #define ELFCLASS ELFCLASS32
87 #define ELFMACHINE EM_386
88 #define CS_MODE CS_MODE_32
89 #define RELOC_MODE RELOC_X86_32
102 unsigned long int pcounter = 0;
103 unsigned int page_size = 4096;
105 unsigned long long int i, j, r;
107 printf(
GREEN "\n Memory segments\n\n");
112 if (pcounter++ == 10000) {
114 printf(
" %016llx\r", i);
117 if (msync((
void *) i, page_size, MS_ASYNC)) {
122 for (j = 0; j < 0x100000000; j += page_size) {
123 if (msync((
void *) i + j, page_size, 0)) {
127 printf(
NORMAL " %016llx-%016llx\n" GREEN, i, i + j);
138 int ptoh(
int perms,
char hperms[])
140 snprintf(hperms, 5,
"%s%s%s", (perms & 0x04) ?
"r" :
"-", (perms & 0x02) ?
"w" :
"-", (perms & 0x01) ?
"x" :
"-");
151 printf(
" -- %s() = %p from %s:%p\n", dli.dli_sname, dli.dli_saddr, dli.dli_fname, dli.dli_fbase);
159 fprintf(stderr,
"\nFATAL ERROR:\n %s: %s\n\n", msg,
lua_tostring(L, -1));
169 printf(
" -- Running lua script %s\n", path);
184 void hexdump(uint8_t * data,
size_t size,
size_t colorstart,
size_t color_len)
189 for (j = 0; j < size; j += 16) {
195 printf(
"%p ", data + j);
201 for (i = j; i < j + 16; i++) {
204 if ((wsh->
opt_hollywood) && (color_len) && (colorstart == i)) {
207 if ((wsh->
opt_hollywood) && (color_len) && (colorstart + color_len == i)) {
212 printf(
"%02x ", data[i] & 255);
220 for (i = j; i < j + 16; i++) {
223 if ((wsh->
opt_hollywood) && (color_len) && (colorstart == i)) {
226 if ((wsh->
opt_hollywood) && (color_len) && (colorstart + color_len == i)) {
231 putchar(32 <= (data[i] & 127) && (data[i] & 127) < 127 ? data[i] & 127 :
'.');
243 static unsigned long int resolve_addr(
char *symbol,
char *libname)
246 unsigned long int ret = 0;
247 struct link_map *handle;
250 if ((!symbol) || (!*symbol)) {
256 fprintf(stderr,
"ERROR: %s\n", dlerror());
262 ret = (
unsigned long int) dlsym(handle, symbol);
264 dladdr((
void *) ret, &dli);
267 if ((dli.dli_fname) && (libname) && (strlen(libname)) && (strncmp(libname, dli.dli_fname, strlen(libname)))) {
340 unsigned long int ret = 0;
342 struct link_map *handle;
345 unsigned int stype, sbind, i;
346 char *htype = 0, *hbind = 0;
350 fprintf(stderr,
"ERROR: %s\n", dlerror());
356 ret = (
unsigned long int) dlsym(handle, symbol);
358 if (dladdr1(ret, &dli, (
void **) &s, RTLD_DL_SYMENT)) {
366 retv =
add_symbol(symbol, libname, htype, hbind, s->st_value, s->st_size, ret);
367 if(retv){
return retv;}
384 char *opt, *word = 0;
385 unsigned int p, w = 0;
397 DL_FOREACH_SAFE(wsh->
symbols, s, stmp) {
408 for (p = strlen(opt); p > 0; p--) {
409 if ((opt[p] == 0x20)||(opt[p] == 0x28)) {
417 if (strlen(word) == n) {
435 DL_FOREACH_SAFE(wsh->
symbols, s, stmp) {
436 if (!strncmp(buf, s->
symbol, strlen(buf))) {
462 fprintf(stderr,
"!! ERROR : open(%s, O_RDWR) %s\n",
PROC_ASLR_PATH, strerror(errno));
481 fprintf(stderr,
"!! ERROR : open(%s,O_RDWR) %s\n",
PROC_ASLR_PATH, strerror(errno));
499 {
"quit",
"",
"Exit wsh.",
"",
"Does not return : exit wsh\n"},
500 {
"exit",
"",
"Exit wsh.",
"",
"Does not return : exit wsh\n"},
501 {
"shell",
"[command]",
"Run a /bin/sh shell.",
"",
"None. Returns uppon shell termination."},
502 {
"exec",
"<command>",
"Run <command> via the system() library call.",
"",
"None. Returns uppon <command> termination."},
503 {
"clear",
"",
"Clear terminal.",
"",
"None."},
507 {
"help",
"[topic]",
"Display help on [topic]. If [topic] is ommitted, display general help.",
"",
"None"},
508 {
"man",
"[page]",
"Display system manual page for [page].",
"",
"None"},
509 {
"hexdump",
"<address>, <num>",
"Display <num> bytes from memory <address> in enhanced hexadecimal form.",
"",
"None"},
510 {
"hex",
"<object>",
"Display lua <object> in enhanced hexadecimal form.",
"",
"None"},
511 {
"phdrs",
"",
"Display ELF program headers from all binaries loaded in address space.",
"",
"None"},
512 {
"shdrs",
"",
"Display ELF section headers from all binaries loaded in address space.",
"",
"None"},
513 {
"map",
"",
"Display a table of all the memory ranges mapped in memory in the address space.",
"",
"None"},
514 {
"procmap",
"",
"Display a table of all the memory ranges mapped in memory in the address space as displayed in /proc/<pid>/maps.",
"",
"None"},
515 {
"bfmap",
"",
"Bruteforce valid mapped memory ranges in address space.",
"",
"None"},
516 {
"symbols",
"[sympattern], [libpattern], [mode]",
"Display all the symbols in memory matching [sympattern], from library [libpattern]. If [mode] is set to 1 or 2, do not wait user input between pagers. [mode] = 2 provides a shorter output.",
"",
"None"},
517 {
"functions",
"[sympattern], [libpattern], [mode]",
"Display all the functions in memory matching [sympattern], from library [libpattern]. If [mode] is set to 1 or 2, do not wait user input between pagers. [mode] = 2 provides a shorter output.",
"table func = ",
"Return 1 lua table _func_ whose keys are valid function names in address space, and values are pointers to them in memory."},
518 {
"objects",
"[pattern]",
"Display all the functions in memory matching [sympattern]",
"",
"None"},
519 {
"info",
"[address] | [name]",
"Display various informations about the [address] or [name] provided : if it is mapped, and if so from which library and in which section if available.",
"",
"None"},
520 {
"search",
"<pattern>",
"Search all object names matching <pattern> in address space.",
"",
"None"},
521 {
"headers",
"",
"Display C headers suitable for linking against the API loaded in address space.",
"",
"None"},
522 {
"grep",
"<pattern>, [patternlen], [dumplen], [before]",
"Search <pattern> in all ELF sections in memory. Match [patternlen] bytes, then display [dumplen] bytes, optionally including [before] bytes before the match. Results are displayed in enhanced decimal form",
"table match = ",
"Returns 1 lua table containing matching memory addresses."},
523 {
"grepptr",
"<pattern>, [patternlen], [dumplen], [before]",
"Search pointer <pattern> in all ELF sections in memory. Match [patternlen] bytes, then display [dumplen] bytes, optionally including [before] bytes before the match. Results are displayed in enhanced decimal form",
"table match = ",
"Returns 1 lua table containing matching memory addresses."},
524 {
"loadbin",
"<pathname>",
"Load binary to memory from <pathname>.",
"",
"None"},
525 {
"libs",
"",
"Display all libraries loaded in address space.",
"table libraries = ",
"Returns 1 value: a lua table _libraries_ whose values contain valid binary names (executable/libraries) mapped in memory."},
526 {
"entrypoints",
"",
"Display entry points for each binary loaded in address space.",
"",
"None"},
527 {
"rescan",
"",
"Re-perform address space scan.",
"",
"None"},
528 {
"libcall",
"<function>, [arg1], [arg2], ... arg[6]",
"Call binary <function> with provided arguments.",
"void *ret, table ctx = ",
"Returns 2 return values: _ret_ is the return value of the binary function (nill if none), _ctx_ a lua table representing the execution context of the library call.\n"},
529 {
"enableaslr",
"",
"Enable Address Space Layout Randomization (requires root privileges).",
"",
"None"},
530 {
"disableaslr",
"",
"Disable Address Space Layout Randomization (requires root privileges).",
"",
"None"},
531 {
"verbose",
"<verbosity>",
"Change verbosity setting to <verbosity>.",
"",
"None"},
532 {
"breakpoint",
"<address>, [weight]",
"Set a breakpoint at memory <address>. Optionally add a <weight> to breakpoint score if hit.",
"",
"None"},
533 {
"bp",
"<address>, [weight]",
"Set a breakpoint at memory <address>. Optionally add a <weight> to breakpoint score if hit. Alias for breakpoint() function.",
"",
"None"},
534 {
"hollywood",
"<level>",
"Change hollywood (fun) display setting to <level>, impacting color display (enable/disable).",
"",
"None"},
549 if(!strncmp(cmdhelp[i].name, name, strlen(cmdhelp[i].name))){
550 printf(
"\n\tWSH HELP FOR COMMAND %s\n\n\n", name);
551 printf(
"NAME\n\n\t%s\n\nSYNOPSIS\n\n\t%s %s\n\nDESCRIPTION\n\n\t%s\n\nRETURN VALUES\n\n\t%s\n\n\n", cmdhelp[i].name, cmdhelp[i].name, cmdhelp[i].proto, cmdhelp[i].descr, cmdhelp[i].retval);
560 if(!strncmp(fcnhelp[i].name, name, strlen(fcnhelp[i].name))){
561 printf(
"\n\tWSH HELP FOR FUNCTION %s\n\n\n", name);
562 printf(
"NAME\n\n\t%s\n\nSYNOPSIS\n\n\t%s%s(%s)\n\nDESCRIPTION\n\n\t%s\n\nRETURN VALUES\n\n\t%s\n\n\n", fcnhelp[i].name, fcnhelp[i].protoprefix, fcnhelp[i].name, fcnhelp[i].proto, fcnhelp[i].descr, fcnhelp[i].retval);
567 printf(
"ERROR:\tNo help available for function %s()\n", name);
581 printf(
" [Shell commands]\n\n\thelp, quit, exit, shell, exec, clear\n\n");
582 printf(
" [Functions]\n\n");
583 printf(
" + basic:\n\thelp(), man()\n\n");
584 printf(
" + memory display:\n\t hexdump(), hex_dump(), hex()\n\n");
585 printf(
" + memory maps:\n\tshdrs(), phdrs(), map(), procmap(), bfmap()\n\n");
586 printf(
" + symbols:\n\tsymbols(), functions(), objects(), info(), search(), headers()\n\n");
587 printf(
" + memory search:\n\tgrep(), grepptr()\n\n");
588 printf(
" + load libaries:\n\tloadbin(), libs(), entrypoints(), rescan()\n\n");
589 printf(
" + code execution:\n\tlibcall()\n\n");
590 printf(
" + buffer manipulation:\n\txalloc(), ralloc(), xfree(), balloc(), bset(), bget(), rdstr(), rdnum()\n\n");
591 printf(
" + control flow:\n\t breakpoint(), bp()\n\n");
592 printf(
" + system settings:\n\tenableaslr(), disableaslr()\n\n");
593 printf(
" + settings:\n\t verbose(), hollywood()\n\n");
594 printf(
" + advanced:\n\tltrace()\n\nTry help(\"cmdname\") for detailed usage on command cmdname.\n\n");
604 unsigned int pf_x = (flags & 0x1);
605 unsigned int pf_w = (flags & 0x2);
606 unsigned int pf_r = (flags & 0x4);
609 memset(message, 0x00, 20);
611 strcat(message,
"r");
613 strcat(message,
"-");
616 strcat(message,
"w");
618 strcat(message,
"-");
621 strcat(message,
"x");
623 strcat(message,
"-");
625 return strdup(message);
662 return "PT_GNU_EH_FRAME";
665 return "PT_GNU_STACK";
668 return "PT_GNU_RELRO";
673 char *ret = calloc(1, 200);
674 snprintf(ret, 199,
"Unknown: %llx\n", type);
690 for (j = 0; j < info->dlpi_phnum; j++) {
691 p = (
Elf_Phdr *) &info->dlpi_phdr[j];
695 fname = info->dlpi_name;
696 if((!fname)||(strlen(fname) < 2)){
698 if(info->dlpi_addr + p->p_vaddr >= 0x7fd000000000){
709 segment_add(info->dlpi_addr + p->p_vaddr, p->p_memsz, pflags, fname, ptype, p->p_flags);
719 int add_symbol(
char *symbol,
char *libname,
char *htype,
char *hbind,
unsigned long value,
unsigned int size,
unsigned long int addr){
724 if(!s){ fprintf(stderr,
" !! Error: calloc() = %s\n", strerror(errno));
return; }
726 s->
symbol = strdup(symbol);
730 s->
htype = strdup(htype);
731 s->
hbind = strdup(hbind);
734 DL_FOREACH_SAFE(wsh->
symbols, si, stmp) {
751 void section_add(
unsigned long int addr,
unsigned long int size,
char *libname,
char *name,
char *perms,
int flags){
755 if(!s){ fprintf(stderr,
" !! Error: calloc() = %s\n", strerror(errno));
return; }
760 s->
name = strdup(name);
761 s->
perms = strdup(perms);
763 DL_APPEND(wsh->
shdrs, s);
769 void segment_add(
unsigned long int addr,
unsigned long int size,
char *perms,
char *fname,
char *ptype,
int flags){
774 if(!s){ fprintf(stderr,
" !! Error: calloc() = %s\n", strerror(errno));
return; }
779 s->
perms = strdup(perms);
780 s->
type = strdup(ptype);
782 DL_APPEND(wsh->
phdrs, s);
793 s = calloc(1,
sizeof(
eps_t));
794 s->
name = strdup(fname);
797 DL_APPEND(wsh->
eps, s);
807 for (i = 0; i < shnum; i++) {
808 memset(hperms, 0x00, 5);
809 snprintf(hperms, 5,
"%s%s%s", (shdr[i].sh_flags & 0x02) ?
"r" :
"-", (shdr[i].sh_flags & 0x01) ?
"w" :
"-", (shdr[i].sh_flags & 0x04) ?
"x" :
"-");
812 section_add(shdr[i].sh_addr + baseaddr, shdr[i].sh_size, fname, &strTab[shdr[i].sh_name], hperms, shdr[i].sh_flags);
829 fd = open(fname, O_RDONLY);
830 data = mmap(NULL, lseek(fd, 0, SEEK_END), PROT_READ, MAP_SHARED, fd, 0);
836 shdr = (
Elf_Shdr *) (data + elf->e_shoff);
837 strtab = (
char *) (data + shdr[elf->e_shstrndx].sh_offset);
838 scan_section(shdr, strtab, elf->e_shnum, fname, baseaddr);
848 if(strlen(info->dlpi_name) < 2){
872 DL_FOREACH_SAFE(wsh->
shdrs, s, stmp) {
887 DL_FOREACH_SAFE(wsh->
phdrs, s, stmp) {
902 DL_FOREACH_SAFE(wsh->
symbols, s, stmp) {
917 DL_FOREACH_SAFE(wsh->
symbols, s, stmp) {
918 if(!strncmp(fname,s->
symbol,strlen(fname))){
934 unsigned int i, scount = 0;
935 unsigned int pcnt = 0;
941 printf(
"/**\n*\n* Automatically generated by the Whitchcraft Compiler Collection %s\n*\n* %s %s\n*\n*/\n\n\n", WVERSION, WTIME, WDATE);
946 printf(
"/**\n* Imported objects\n**/\n");
947 DL_FOREACH_SAFE(wsh->
symbols, s, stmp) {
949 if((!libname)||(strstr(s->
libname, libname))){
950 if(!strncmp(s->
htype,
"Object",6)){
952 printf(
"extern void *%s;\n", s->
symbol);
961 printf(
"\n\n/**\n* Imported functions\n**/\n");
962 DL_FOREACH_SAFE(wsh->
symbols, s, stmp) {
964 if((!libname)||(strstr(s->
libname, libname))){
965 if(strncmp(s->
htype,
"Object",6)){
966 if(strncmp(s->
symbol,
"main", 5)){
967 printf(
"void *%s();\n", s->
symbol);
983 DL_FOREACH_SAFE(wsh->
symbols, s, stmp) {
1002 DL_FOREACH_SAFE(wsh->
phdrs, s, stmp) {
1003 DL_DELETE(wsh->
phdrs, s);
1021 DL_FOREACH_SAFE(wsh->
shdrs, s, stmp) {
1022 DL_DELETE(wsh->
shdrs, s);
1039 DL_FOREACH_SAFE(wsh->
eps, s, stmp) {
1040 DL_DELETE(wsh->
eps, s);
1056 unsigned int scount = 0;
1057 DL_COUNT(wsh->
phdrs, s, scount);
1059 printf(
" -- Total: %u segments\n", scount);
1061 DL_FOREACH_SAFE(wsh->
phdrs, s, stmp) {
1062 if(strncmp(lastlib,s->
libname,strlen(lastlib))){
1094 printf(
"%012llx-%012llx\t%s\t%u\t%s\t%s\n", s->
addr, s->
addr + s->
size,
1100 printf(
" -- Total: %u segments\n", scount);
1110 unsigned int scount = 0;
1113 unsigned int pcnt = 0;
1116 unsigned int returnall = 0;
1122 DL_COUNT(wsh->
symbols, s, scount);
1125 printf(
" -- Total: %u symbols\n", scount);
1126 printf(
" -- Symbols:\n\n");
1128 printf(
"-----------------------------------------------------------------------------------------------------------------\n");
1134 DL_FOREACH_SAFE(wsh->
symbols, s, stmp) {
1135 if((!symname)||(strstr(s->
symbol, symname))){
1136 if((!libname)||(strstr(s->
libname, libname))){
1140 for (i = strlen(s->
libname); i < 40; i++)
1142 printf(
"%s ", s->
symbol);
1143 for (i = strlen(s->
symbol); i < 30; i++)
1145 printf(
"%s ", s->
htype);
1146 for (i = strlen(s->
htype); i < 10; i++)
1157 if((!returnall)&&(pcnt ==
LINES_MAX)){ pcnt = 0;
int c = getchar();
switch(c){
case 0x61: pcnt =
LINES_MAX + 1;
break;
case 0x71:
return 0;
break;
default:
break; }; }
1164 printf(
" -- %u symbols matched\n", pcnt);
1178 unsigned int scount = 0;
1181 unsigned int pcnt = 0;
1184 unsigned int returnall = 0;
1190 DL_COUNT(wsh->
symbols, s, scount);
1193 printf(
" -- Total: %u symbols\n", scount);
1194 printf(
" -- Functions:\n");
1195 printf(
"-----------------------------------------------------------------------------------------------------------------\n");
1203 DL_FOREACH_SAFE(wsh->
symbols, s, stmp) {
1205 if(!strncmp(s->
htype,
"Function",8)){
1207 if((!symname)||(strstr(s->
symbol, symname))){
1209 if((!libname)||(strstr(s->
libname, libname))){
1215 for (i = strlen(s->
libname); i < 40; i++)
1217 printf(
"%s ", s->
symbol);
1218 for (i = strlen(s->
symbol); i < 30; i++)
1220 printf(
"%s ", s->
htype);
1221 for (i = strlen(s->
htype); i < 10; i++)
1234 if((!returnall)&&(pcnt ==
LINES_MAX)){ pcnt = 0;
int c = getchar();
switch(c){
case 0x61: pcnt =
LINES_MAX + 1;
break;
case 0x71:
return 0;
break;
default:
break; }; }
1243 printf(
" -- %u functions matched\n", scount);
1257 unsigned int scount = 0;
1260 unsigned int pcnt = 0;
1266 DL_COUNT(wsh->
symbols, s, scount);
1267 printf(
" -- Total: %u symbols\n", scount);
1270 printf(
" -- Objects:\n\n");
1272 printf(
"-----------------------------------------------------------------------------------------------------------------\n");
1275 DL_FOREACH_SAFE(wsh->
symbols, s, stmp) {
1277 if((!libname)||(strstr(s->
libname, libname))){
1279 if(!strncmp(s->
htype,
"Object",6)){
1282 for (i = strlen(s->
libname); i < 40; i++)
1284 printf(
"%s ", s->
symbol);
1285 for (i = strlen(s->
symbol); i < 30; i++)
1287 printf(
"%s ", s->
htype);
1288 for (i = strlen(s->
htype); i < 10; i++)
1293 if(pcnt ==
LINES_MAX){ pcnt = 0;
int c = getchar();
switch(c){
case 0x61: pcnt =
LINES_MAX + 1;
break;
case 0x71:
return 0;
break;
default:
break; }; }
1300 printf(
" -- %u objects matched\n", scount);
1312 unsigned int scount = 0;
1317 DL_FOREACH_SAFE(wsh->
shdrs, s, stmp) {
1318 if(strncmp(lastlib,s->
libname,strlen(lastlib))){
1333 printf(
" -- Total: %u libraries\n", scount);
1348 unsigned int scount = 0;
1349 char *segmenttype =
"";
1350 char *segmentperms =
"";
1354 DL_COUNT(wsh->
shdrs, s, scount);
1356 printf(
" -- Total: %u sections\n", scount);
1358 DL_FOREACH_SAFE(wsh->
shdrs, s, stmp) {
1359 if(strncmp(lastlib,s->
libname,strlen(lastlib))){
1364 switch(s->
flags&0x0f){
1389 segmenttype = seg->
type;
1390 segmentperms = seg->
perms;
1401 printf(
" -- Total: %u sections\n", scount);
1412 unsigned int scount = 0;
1415 DL_COUNT(wsh->
eps, s, scount);
1417 printf(
" -- Total: %u entry points\n\n", scount);
1419 DL_FOREACH_SAFE(wsh->
eps, s, stmp) {
1420 printf(
"%012llx\t%s\n", s->
addr, s->
name);
1484 memset(cmd, 0x00, 255);
1485 snprintf(cmd, 254,
"man %s", arg);
1498 unsigned long int ret = 0;
1502 unsigned int stype, sbind, i;
1503 char *htype = 0, *hbind = 0;
1507 if(msync(n & ~0xfff, 4096, 0) == 0){
1512 printf(
" * address 0x%llx is mapped\n", n);
1518 if((sym)&&(sym->
addr == n)){
1548 printf(
" * Symbol %s does not exist\n", symbol);
1555 ret = (
unsigned long int) dlsym(wsh->
mainhandle, symbol);
1556 if ((error = dlerror()) != NULL) {
1557 fprintf(stderr,
"ERROR: %s\n", error);
1561 if (dladdr1(ret, &dli, (
void **) &s, RTLD_DL_SYMENT)&&(s)) {
1571 secname = sec->
name;
1574 printf(
" * %s %s %s at %p %s:%s size:%lu\n", htype, hbind, dli.dli_sname, dli.dli_saddr, dli.dli_fname, secname, s->st_size );
1577 printf(
" * symbol %s does not exist.\n", symbol);
1580 printf(
" !! ERROR: info requires a string argument\n");
1597 ptr = calloc(n *
sizeof(
char *), 1);
1607 unsigned int pos = 0;
1661 unsigned int pos = 0;
1691 char *input, shell_prompt[4096];
1696 if (fgets(shell_prompt,
sizeof(shell_prompt), stdin) == 0 || strcmp(shell_prompt,
"cont\n") == 0)
1713 char *SHELL_HISTORY = calloc(1024, 1);
1724 snprintf(shell_prompt,
sizeof(shell_prompt),
"> ");
1726 while ((input =
linenoise(shell_prompt)) != NULL) {
1743 if ((strlen(input) == 5) && (!strncmp(input,
"shell", 5))) {
1744 unsigned int pid = fork();
1747 execlp(
"/bin/sh", 0);
1749 waitpid(pid, &status, 0);
1754 if (!strncmp(input,
"exec ", 5)) {
1759 if ((strlen(input) == 4) && !strncmp(input,
"quit", strlen(input))) {
1761 _Exit(EXIT_SUCCESS);
1763 if ((strlen(input) == 4) && !strncmp(input,
"exit", strlen(input))) {
1765 _Exit(EXIT_SUCCESS);
1767 if ((strlen(input) == 4) && !strncmp(input,
"help", strlen(input))) {
1772 if ((strlen(input) == 5) && !strncmp(input,
"clear", strlen(input))) {
1777 if (!strncmp(input,
"historylen", 10)) {
1779 int len = atoi(input + 10);
1792 free(SHELL_HISTORY);
1795 _Exit(EXIT_SUCCESS);
1801 int learn_proto(
unsigned long*arg,
unsigned long int faultaddr,
int reason){
1804 long int offset = 0;
1806 unsigned int argn = 0;
1808 if(!reason) {
return 0; }
1809 if(!faultaddr) {
return 0; }
1810 if(faultaddr < 0x1000) {
return 0; }
1811 if(faultaddr > 0xf000000000000000) {
return 0; }
1819 tag =
"_output_ptr";
1829 for(i=1; i<=7; i++){
1830 if((faultaddr & ~0xfff) == (arg[i] & ~0xfff)){ argn = i; }
1833 if(!argn){
return 0; }
1835 for(i=1; i<=7; i++){
1836 if((arg[i] == arg[argn])&&(argn != i)){
return 0; }
1839 offset = faultaddr - arg[argn];
1841 if(arg[argn] == 0xffff){
return 0; }
1842 if(arg[argn] == 0x7fff){
return 0; }
1843 if(arg[argn] == 0xffffffff){
return 0; }
1844 if(arg[argn] == 0x7fffffff){
return 0; }
1888 char *patternlib = 0;
1889 char *patterntag = 0;
1906 while (fgets(line,
sizeof(line), wsh->
learnfile)) {
1916 HASH_ADD(hh, protorecords, key,
sizeof(
learn_key_t), l);
1926 printf(
"\n [*] Prototypes: (from %u tag informations)\n", HASH_COUNT(protorecords));
1928 HASH_ITER(hh, protorecords, l, p) {
1929 if((!patternlib) || (strstr(l->
key.
tlib, patternlib))){
1930 if((!pattern) || (!strncmp(pattern, l->
key.
tfunction, strlen(pattern)))){
1931 if((!patterntag) || (strstr(l->
key.
tvalue, patterntag))){
2089 unsigned long int *arg[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2098 for (i = 0; i < 10; i++) {
2127 wsh->
errcontext = calloc(1,
sizeof(ucontext_t));
2133 memset(wsh->
errcontext, 0x00,
sizeof(ucontext_t));
2200 ret = f(arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8]);
2205 unsigned int n = 0, j = 0, notascii = 0;
2228 printf(
"Total: %u misaligned access traced\n", wsh->
sigbus_count);
2229 printf(
"Execution hash: u:%016llx\n", wsh->
sigbus_hash);
2244 for (j = 0; j < strlen(ret); j++) {
2245 if (!isascii((ptr[j]))) {
2261 fprintf(stderr,
"ERROR: (%u) %s\n", errno, strerror(errno));
2335 s = calloc(1,
sizeof(siginfo_t));
2424 memset(argname, 0x00, 10);
2425 snprintf(argname, 9,
"arg%u", j);
2452 for (j = 0; j < strlen(ret); j++) {
2453 if (!isascii((ptr[j]))) {
2509 unsigned int cnt = 0;
2511 unsigned long int address = 0;
2512 char *demangled = 0, *symname = 0;
2513 unsigned int func = 0;
2523 if (sym->st_name >= sz) {
2527 symname = dynstr + sym->st_name;
2555 address = resolve_addr(symname, libname);
2557 address = (
unsigned long int) -1;
2564 if (strlen(symname) && (htype) && (address != (
unsigned long int) -1) && (address)) {
2587 printf(
" * blacklisted function name: %s\n", symname);
2593 memset(newname, 0x00, 1024);
2594 snprintf(newname, 1023,
"reflect_%s", symname);
2600 fprintf(wsh->
scriptfile,
"function %s (a, b, c, d, e, f, g, h) j,k = libcall(%s, a, b, c, d, e, f, g, h); return j, k; end\n",
2612 if((!
scan_symbol(symname, libname))&&(msync(address &~0xfff,4096,0) == 0)) {
2628 unsigned int cnt = 0;
2629 unsigned int done = 0;
2633 unsigned int dynstrsz = 0;
2636 char *sec_initarray = 0;
2637 unsigned long int sec_initarraysz = 0;
2638 char *sec_finiarray = 0;
2639 unsigned long int sec_finiarraysz = 0;
2646 while ((dyn) && (!done)) {
2649 switch (dyn->d_tag) {
2681 dynstr = (
char *) dyn->d_un.d_val;
2684 dynsym = (
Elf_Sym *) dyn->d_un.d_val;
2687 dynstrsz = dyn->d_un.d_val;
2690 sec_init = (
char *) dyn->d_un.d_val;
2693 sec_fini = (
char *) dyn->d_un.d_val;
2696 sec_initarray = (
char *) dyn->d_un.d_val;
2698 case DT_INIT_ARRAYSZ:
2699 sec_initarraysz = dyn->d_un.d_val;
2702 sec_finiarray = (
char *) dyn->d_un.d_val;
2704 case DT_FINI_ARRAYSZ:
2705 sec_finiarraysz = dyn->d_un.d_val;
2720 scan_syms(dynstr, dynsym, dynstrsz, map->l_name);
2727 fprintf(stderr,
"ERROR: No binary to execute\n");
2728 _Exit(EXIT_FAILURE);
2731 while ((map) && (map->l_prev)) {
2772 memset(path, 0x00, 100);
2773 snprintf(path, 99,
"/proc/%u/maps", pid);
2774 buff = calloc(1, 4096);
2775 fd = open(path, O_RDONLY);
2776 if(fd < 0){ printf(
" !! ERROR: open %s : %s\n", path, strerror(errno));
return -1; }
2778 while ((n = read(fd, buff, 4096)) > 0){
2780 memset(buff, 0x00, 4096);
2795 unsigned int ret = 0;
2802 ptrace(PTRACE_TRACEME, 0, 0, 0);
2805 _Exit(EXIT_SUCCESS);
2806 }
else if (child == -1) {
2807 fprintf(stderr,
"ERROR: fork() : %s\n", strerror(errno));
2808 _Exit(EXIT_FAILURE);
2810 ptrace(PTRACE_SETOPTIONS, child, 0, PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK | PTRACE_O_TRACECLONE | PTRACE_O_TRACEEXEC | PTRACE_O_TRACEVFORKDONE | PTRACE_O_TRACEEXIT);
2813 if (waitpid(-1, &status, __WALL) == -1) {
2814 printf(
" [*] traced process exited with status %d\n", WEXITSTATUS(status));
2815 _Exit(EXIT_FAILURE);
2817 if (WIFSTOPPED(status)) {
2819 if (ptrace(PTRACE_CONT, child, 0, 0) == -1) {
2820 fprintf(stderr,
"ERROR: ptrace() : %s\n", strerror(errno));
2821 _Exit(EXIT_FAILURE);
2824 ptrace(PTRACE_GETSIGINFO, pid, NULL, &si);
2825 if (si.si_signo || si.si_errno || si.si_code) {
2826 printf(
"[*] Child stopped with signal: %i" " errno: %i code: %i\n", si.si_signo, si.si_errno, si.si_code);
2850 void *traceptrs[100];
2856 count = backtrace(traceptrs, 100);
2857 funcnames = backtrace_symbols(traceptrs, count);
2863 p = strchr(funcnames[i], 0x20);
2867 printf(
"\t%012lx %s\n", traceptrs[i], funcnames[i]);
2882 if (
signames[i].signal == signal) {
2886 return "Unknown Signal";
2893 asm(
".intel_syntax noprefix;"
2907 asm(
".intel_syntax noprefix;"
2920 asm(
".intel_syntax noprefix;"
2934 asm(
".intel_syntax noprefix;"
2951 CPU_SET(procnum, &set);
2953 if (sched_setaffinity(getpid(),
sizeof(set), &set) == -1){
2954 fprintf(stderr,
" !! ERROR: sched_setaffinity(%u): %s\n", procnum, strerror(errno));
2963 uint64_t data = 0x02;
2966 memset(cpupath, 0x00, 200);
2967 snprintf(cpupath, 199,
"/dev/cpu/%d/msr", procnum);
2968 fd = open(cpupath, O_WRONLY);
2969 if(fd <= 0){ fprintf(stderr,
"ERROR: open(%s): %s\n", cpupath,strerror(errno));
return; }
2970 ret = lseek(fd, 0x00, SEEK_SET);
2971 if(ret != 0x00){ fprintf(stderr,
"ERROR: lseek(): %s\n", strerror(errno));
return; }
2972 ret = pwrite(fd, &data,
sizeof(data), 0x1d9);
2973 if(ret !=
sizeof(data)){ fprintf(stderr,
"ERROR: write(): %s\n", strerror(errno));
return; }
2975 if(ret != 0){ fprintf(stderr,
"ERROR: close(): %s\n", strerror(errno));
return; }
2983 uint64_t data = 0x00;
2986 memset(cpupath, 0x00, 200);
2987 snprintf(cpupath, 199,
"/dev/cpu/%d/msr", procnum);
2988 fd = open(cpupath, O_WRONLY);
2989 if(fd <= 0){ fprintf(stderr,
"ERROR: open(%s): %s\n", cpupath,strerror(errno));
return; }
2990 ret = lseek(fd, 0x00, SEEK_SET);
2991 if(ret != 0x00){ fprintf(stderr,
"ERROR: lseek(): %s\n", strerror(errno));
return; }
2992 ret = pwrite(fd, &data,
sizeof(data), 0x1d9);
2993 if(ret !=
sizeof(data)){ fprintf(stderr,
"ERROR: write(): %s\n", strerror(errno));
return; }
2995 if(ret != 0){ fprintf(stderr,
"ERROR: close(): %s\n", strerror(errno));
return; }
3033 ucontext_t *u = (ucontext_t *) ptr;
3068 fprintf(stderr,
" -- SIGBUS[%03u] %llx\n", wsh->
sigbus_count+1, u->uc_mcontext.gregs[
REG_RIP]);
3076 u->uc_mcontext.gregs[REG_EFL] ^= 0x40000;
3077 u->uc_mcontext.gregs[REG_EFL]|= 0x100;
3086 write(1,
"\n[SIGALRM]\tTimeout",18);
3097 write(1,
"\n[SIGINT]\tInterrupted",21);
3117 bt_size = backtrace(bt, 20);
3118 bt_syms = backtrace_symbols(bt, bt_size);
3120 for (i = 2; i < bt_size; i++) {
3122 write(1, bt_syms[i], strlen(bt_syms[i]));
3138 fprintf(stderr,
" + Called exit(%d), restoring...\n", status);
3144 fprintf(stderr,
" + Called _exit(%d), restoring...\n", status);
3150 fprintf(stderr,
" + Called exit_group(%d), restoring...\n", status);
3156 if(msync(val &~0xfff,4096,0) == 0){
3157 int nlen, noflag, k;
3161 nlen = strnlen(ptrx, 4096 - ((
unsigned long int)ptrx & ~0xfff));
3163 for(k=0;k<nlen;k++){
if(!isprint(ptrx[k] & 0xff)){ ;noflag = 1; }; }
3166 fprintf(stderr,
"\"%s\"", ptrx);
3168 fprintf(stderr,
"0x%lx", val);
3171 fprintf(stderr,
"0x%lx", val);
3179 ucontext_t *u = (ucontext_t *) ptr;
3180 unsigned int fault = 0;
3194 for (i = 0; i < wsh->
bp_num; i++) {
3196 printf(
" ** EXECUTED BREAKPOINT[%u] at %p weight:%u <", i + 1, u->uc_mcontext.gregs[
REG_RIP] - 1, wsh->
bp_array[i].
weight);
3198 ptrd = u->uc_mcontext.gregs[
REG_RIP] - 1;
3214 printf(
" ** Restoring execution from %p\n", ptrd);
3215 u->uc_mcontext.gregs[
REG_RIP]--;
3222 if((u->uc_mcontext.gregs[
REG_RIP] & ~0xffffff) != ((
unsigned long int)
traphandler & ~0xffffff)){
3225 if((s)&&(u->uc_mcontext.gregs[
REG_RIP] == s->
addr)){
3229 printarg(u->uc_mcontext.gregs[REG_RDI]);
3230 fprintf(stderr,
", ");
3231 printarg(u->uc_mcontext.gregs[REG_RSI]);
3232 fprintf(stderr,
", ");
3233 printarg(u->uc_mcontext.gregs[REG_RDX]);
3234 fprintf(stderr,
", ");
3235 printarg(u->uc_mcontext.gregs[REG_RCX]);
3236 fprintf(stderr,
", ");
3237 printarg(u->uc_mcontext.gregs[REG_R8]);
3238 fprintf(stderr,
", ");
3239 printarg(u->uc_mcontext.gregs[REG_R9]);
3243 fprintf(stderr,
")\t%s\n", s->
libname);
3257 u->uc_mcontext.gregs[REG_EFL] |= 0x100;
3265 if((u->uc_mcontext.gregs[
REG_RIP] & ~0xffffff) != ((
unsigned long int)
traphandler & ~0xffffff)){
3269 if((s)&&(u->uc_mcontext.gregs[
REG_RIP] == s->
addr)){
3274 printarg(u->uc_mcontext.gregs[REG_RDI]);
3275 fprintf(stderr,
", ");
3276 printarg(u->uc_mcontext.gregs[REG_RSI]);
3277 fprintf(stderr,
", ");
3278 printarg(u->uc_mcontext.gregs[REG_RDX]);
3279 fprintf(stderr,
", ");
3280 printarg(u->uc_mcontext.gregs[REG_RCX]);
3281 fprintf(stderr,
", ");
3282 printarg(u->uc_mcontext.gregs[REG_R8]);
3283 fprintf(stderr,
", ");
3284 printarg(u->uc_mcontext.gregs[REG_R9]);
3287 fprintf(stderr,
")\t%s\n", s->
libname);
3297 u->uc_mcontext.gregs[REG_EFL] |= 0x100;
3304 u->uc_mcontext.gregs[REG_EFL] |= 0x40000;
3305 u->uc_mcontext.gregs[REG_EFL] ^= 0x100;
3312 if (u->uc_mcontext.gregs[REG_ERR] & 0x2) {
3315 }
else if (s->si_addr == u->uc_mcontext.gregs[
REG_RIP]) {
3324 fprintf(stderr,
"%s\t(%u)\trip:%p %s\t%08lx\t", signame, signal, u->uc_mcontext.gregs[
REG_RIP], hfault, s->si_addr);
3327 printf(
" -- No corresponding breakpoint (among %u), exiting\n", wsh->
bp_num);
3328 _Exit(EXIT_SUCCESS);
3346 switch (s->si_code) {
3348 sicode =
"invalid address alignment";
3351 sicode =
"non-existent physical address";
3354 sicode =
"object specific hardware error";
3359 switch (s->si_code) {
3361 sicode =
"child has exited";
3364 sicode =
"child was killed";
3367 sicode =
"child terminated abnormally";
3370 sicode =
"traced child has trapped";
3373 sicode =
"child has stopped";
3376 sicode =
"stopped child has continued";
3381 switch (s->si_code) {
3383 sicode =
"illegal opcode";
3386 sicode =
"illegal operand";
3389 sicode =
"illegal addressing mode";
3392 sicode =
"illegal trap";
3395 sicode =
"privileged opcode";
3398 sicode =
"privileged register";
3401 sicode =
"coprocessor error";
3404 sicode =
"internal stack error";
3409 switch (s->si_code) {
3411 sicode =
"integer divide by zero";
3414 sicode =
"integer overflow";
3417 sicode =
"floating point divide by zero";
3420 sicode =
"floating point overflow";
3423 sicode =
"floating point underflow";
3426 sicode =
"floating point inexact result";
3429 sicode =
"invalid floating point operation";
3432 sicode =
"subscript out of range";
3437 switch (s->si_code) {
3439 sicode =
"address not mapped to object";
3442 sicode =
"invalid permissions for mapped object";
3445 sicode =
"segmentation fault";
3456 ucontext_t *u = (ucontext_t *) ptr;
3457 unsigned int fault = 0;
3461 char defsicode[200];
3463 char *accesscolor =
"";
3469 if (u->uc_mcontext.gregs[REG_ERR] & 0x2) {
3474 }
else if (s->si_addr == u->uc_mcontext.gregs[
REG_RIP]) {
3483 accesscolor =
GREEN;
3496 memset(defsicode, 0x00, 200);
3497 snprintf(defsicode, 199,
"Error code %d", s->si_code);
3502 fprintf(stderr,
"\n%s[%s]\t%s\t%012lx" BLUE " (%s)\n" NORMAL, accesscolor, signame, hfault, s->si_addr, sicode);
3504 if((fault !=
FAULT_EXEC)||(!msync(u->uc_mcontext.gregs[
REG_RIP]&~0xfff, getpagesize(), 0))){
3515 memcpy(wsh->
errcontext, u,
sizeof(ucontext_t));
3527 fprintf(stderr,
" !! FATAL ERROR: Instruction Pointer 0x%012llx addr:%012llx\n", u->uc_mcontext.gregs[
REG_RIP], s->si_addr);
3535 errno = ENOTRECOVERABLE;
3544 struct sigaction sa;
3546 sa.sa_flags = SA_SIGINFO | SA_RESTART;
3547 sigemptyset(&sa.sa_mask);
3549 if (sigaction(SIGSEGV, &sa, NULL) == -1) {
3550 perror(
"sigaction");
3551 _Exit(EXIT_FAILURE);
3554 if (sigaction(SIGABRT, &sa, NULL) == -1) {
3555 perror(
"sigaction");
3556 _Exit(EXIT_FAILURE);
3559 if (sigaction(SIGILL, &sa, NULL) == -1) {
3560 perror(
"sigaction");
3561 _Exit(EXIT_FAILURE);
3564 sa.sa_flags = SA_SIGINFO;
3566 if (sigaction(SIGTRAP, &sa, NULL) == -1) {
3567 perror(
"sigaction");
3568 _Exit(EXIT_FAILURE);
3571 sa.sa_flags = SA_SIGINFO;
3573 if (sigaction(SIGALRM, &sa, NULL) == -1) {
3574 perror(
"sigaction");
3575 _Exit(EXIT_FAILURE);
3578 sa.sa_flags = SA_SIGINFO;
3580 if (sigaction(SIGINT, &sa, NULL) == -1) {
3581 perror(
"sigaction");
3582 _Exit(EXIT_FAILURE);
3586 sa.sa_flags = SA_SIGINFO ;
3587 sigfillset(&sa.sa_mask);
3588 if (sigaction(SIGBUS, &sa, NULL) == -1) {
3589 perror(
"sigaction");
3590 _Exit(EXIT_FAILURE);
3604 fds.events = POLLIN;
3605 ret = poll(&fds, 1, 0);
3609 }
else if (ret == 0) {
3626 printf(
" -- Setting verbosity to %u\n", arg);
3640 printf(
" -- Setting hollywood to %u\n", arg);
3660 unsigned int count = 0;
3662 char *sizes[] = {
"b",
"Kb",
"Mb",
"Gb",
"Tb",
"Pb",
"Hb" };
3690 printf(
"%012llx-%012llx %s %s\t\t%u\n", s->
init, s->
end, s->
hperms, s->
name, s->
size / sysconf(_SC_PAGE_SIZE));
3693 count += s->
size / sysconf(_SC_PAGE_SIZE);
3698 len = count * sysconf(_SC_PAGE_SIZE);
3700 while ((len >= 1024) && (order <= 3)) {
3705 printf(
" --> total: %u pages mapped (%d %s)\n", count, (
unsigned int) len, sizes[order]);
3715 unsigned int num = 0;
3716 DL_FOREACH_SAFE(wsh->
shdrs, s, stmp) {
3717 if((s->
name)&&(!strncmp(s->
name,
".bss",4))){
3733 static char *searchmem(
char *start,
char *pattern,
unsigned int patternlen,
unsigned int memsz)
3740 uplim = memsz - patternlen;
3742 for (i = 0; (i >= 0) && (i < uplim) && (uplim > 0); i++) {
3743 if (!memcmp(ptr + i, pattern, patternlen)) {
3757 unsigned char poison;
3758 unsigned long int ret = 0;
3760 unsigned long int *ptr2;
3761 unsigned int sz = 0;
3762 unsigned long int baseaddr = 0;
3770 ptr = mmap(baseaddr, sz, PROT_WRITE|PROT_READ, MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0);
3773 fprintf(stderr,
" !! ERROR: malloc() : %s",strerror(errno));
3780 printf(
"-- ralloc() ptr:%llx, size:%u, ret:%llx\t[%llx-%llx]\n", ptr, sz, ret, ret, ret + size);
3783 mprotect(ptr, sz, PROT_EXEC | PROT_READ | PROT_WRITE);
3788 memset(ptr,poison, size % 4096);
3790 mprotect(ptr, sz, PROT_READ);
3811 unsigned char poison;
3812 unsigned long int ret = 0;
3814 unsigned long int *ptr2;
3815 unsigned int sz = 0;
3816 unsigned long int baseaddr = 0;
3824 sz = getpagesize()*3;
3827 ptr = mmap(baseaddr, sz, PROT_WRITE|PROT_READ, MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0);
3830 fprintf(stderr,
" !! ERROR: malloc() : %s",strerror(errno));
3834 ret = ptr + 2*getpagesize() -
size;
3837 printf(
"-- ptr:%llx, size:%u, ret:%llx\t[%llx-%llx]\n", ptr, sz, ret, ret, ret + size);
3840 mprotect(ptr, sz, PROT_EXEC | PROT_READ | PROT_WRITE);
3847 for(ptr2 = ptr; ptr2 < ptr + sz ; ptr2++){
3851 for(ptr2 = ret; ptr2 < ret +
size ; ptr2++){
3856 mprotect(ptr, sz, perms ? perms : PROT_READ | PROT_WRITE | PROT_EXEC);
3858 mprotect(ptr+2*getpagesize(), getpagesize(), PROT_NONE);
3869 void *ptr = 0, *trueptr = 0;
3870 unsigned int sz = 0;
3872 sz = 3*getpagesize();
3875 trueptr = ((
unsigned long int)ptr & ~0xfff)-0x1000;
3876 mprotect(trueptr, sz, PROT_EXEC | PROT_READ | PROT_WRITE);
3877 memset(trueptr, 0x00, sz);
3878 munmap(trueptr, sz);
3953 fprintf(stderr,
"!! ERROR: You need root privileges to use Branch Tracing\n");
3958 system(
"sudo modprobe cpuid");
3959 system(
"sudo modprobe msr");
3982 unsigned long int maxlen = 0, i = 0;
3985 unsigned int dumplen = 200;
3988 unsigned long int p;
3990 unsigned int patternsz = 0;
3991 unsigned int aligned = 0;
4000 patternsz =
sizeof(
unsigned long int);
4002 if (patternsz > 8) {
4003 fprintf(stderr,
"ERROR: Wrong pattern size:%u > 8\n", patternsz);
4006 printf(
" -- Searching Pointer: 0x%lx (length:%u aligned:%u)\n", p, patternsz, aligned);
4007 memset(pattern, 0x00, 9);
4008 memcpy(pattern, &p, patternsz);
4013 DL_FOREACH_SAFE(wsh->
shdrs, s, stmp) {
4015 if (!msync(s->
addr&~0xfff, s->
size, 0)) {
4017 match = searchmem(s->
addr + k, pattern, patternsz, s->
size - k);
4023 printf(
" match[%d] at %p %u bytes within:%llx-%llx:%s:%s:%s\n\n", count, match, match - (
char *) s->
addr, s->
addr, s->
addr + s->
size, s->
name, s->
perms);
4025 int delta = (
char *) (s->
addr+s->
size) - match;
4026 if (delta > dumplen) {
4029 hexdump(match, patternsz + delta, 0, patternsz);
4038 k = match - s->
addr + 1;
4072 unsigned int maxlen = 0, i = 0;
4076 unsigned int patternlen = 0;
4077 unsigned int dumplen = 0;
4078 unsigned int nbytesbeforematch = 0;
4090 patternlen = strlen(pattern);
4099 DL_FOREACH_SAFE(wsh->
shdrs, s, stmp) {
4101 if (!msync(s->
addr&~0xfff, s->
size, 0)) {
4103 match = searchmem(s->
addr + k, pattern, patternlen, s->
size - k);
4109 printf(
" match[%d] at %p %u bytes within:%llx-%llx:%s:%s:%s\n\n", count + 1, match, match - (
char *) s->
addr, s->
addr, s->
addr + s->
size, s->
name, s->
perms);
4111 int delta = (
char *) (s->
addr+s->
size) - match;
4112 if (delta > dumplen) {
4115 hexdump(match - nbytesbeforematch, patternlen + delta, nbytesbeforematch, patternlen);
4124 k = match - s->
addr + 1;
4139 static struct section *sec_from_addr(
unsigned long int addr)
4144 if ((s->
init <= addr) && (s->
end > addr)) {
4156 void *arg1 = 0, *arg2 = 0, *arg3 = 0;
4165 ret = memcpy(arg1, arg2, arg3);
4178 void *arg1 = 0, *arg2 = 0;
4186 ret = strcpy(arg1, arg2);
4199 void *arg1 = 0, *arg2 = 0;
4207 ret = strcat(arg1, arg2);
4220 void *arg1 = 0, *arg2 = 0;
4231 fprintf(stderr,
"ERROR: Address %p is not mapped\n", arg1);
4239 addr = ((
unsigned long int) ptr & (
unsigned long int) ~0xfff);
4240 printf(
" ** Setting BREAKPOINT[%u] (weigth:%u) <", wsh->
bp_num + 1, arg2);
4242 mprotect(addr, sysconf(_SC_PAGE_SIZE), PROT_READ | PROT_WRITE | PROT_EXEC);
4247 char bk = ptr[0x00];
4301 fprintf(wsh->
scriptfile,
"function %s (a, b, c, d, e, f, g, h) j,k = libcall(%s, a, b, c, d, e, f, g, h); return j, k; end\n",
"hexdump",
"lhexdump");
4302 fprintf(wsh->
scriptfile,
"function %s (a, b, c, d, e, f, g, h) j,k = libcall(%s, a, string.len(a), c, d, e, f, g, h); return j, k; end\n",
"hex",
"lhexdump");
4303 fprintf(wsh->
scriptfile,
"function %s (a, b, c, d, e, f, g, h) j,k = libcall(%s, a, b, c, d, e, f, g, h); return j, k; end\n",
"execlib",
"lexeclib");
4304 fprintf(wsh->
scriptfile,
"function %s (a, b, c, d, e, f, g, h) j,k = libcall(%s, a, b, c, d, e, f, g, h); return j, k; end\n",
"disasm",
"ldisasm");
4305 fprintf(wsh->
scriptfile,
"function %s (a, b, c, d, e, f, g, h) j,k = libcall(%s, a, b, c, d, e, f, g, h); return j, k; end\n",
"deref",
"lderef");
4306 fprintf(wsh->
scriptfile,
"function %s (a, b, c, d, e, f, g, h) j,k = libcall(%s, a, b, c, d, e, f, g, h); return j, k; end\n",
"strace",
"lstrace");
4307 fprintf(wsh->
scriptfile,
"function %s (a, b, c, d, e, f, g, h) j,k = libcall(%s, a, b, c, d, e, f, g, h); return j, k; end\n",
"script",
"lscript");
4313 struct link_map *handle;
4315 handle = dlopen(libname, RTLD_NOW);
4317 fprintf(stderr,
"ERROR: %s\n", dlerror());
4318 _Exit(EXIT_FAILURE);
4322 printf(
" -- Base address: %p of %s\n", (
void *) handle->l_addr, libname);
4332 setenv(
"LIBC_FATAL_STDERR_",
"yes", 1);
4333 mallopt(M_CHECK_ACTION, 3);
4343 kill(getpid(), SIGQUIT);
4352 prctl(PR_SET_DUMPABLE, (
long)0);
4360 prctl(PR_SET_DUMPABLE, (
long)1);
4369 wsh = calloc(1,
sizeof(
wsh_t));
4380 snprintf(wsh->
scriptname, 254,
"/tmp/self.%u.lua", getpid());
4401 return "Runtime Error";
4403 return "Synthax Error";
4405 return "Memory Error";
4407 return "Fatal Error";
4409 return "Unknown Error";
4422 memset(myerror, 0x00, 200);
4425 snprintf(myerror, 199,
"error %d : %s", err,
lua_strerror(err));
4426 printf(stderr,
"luaL_loadfile() failed for script %s (%s)\n", name, errno ? strerror(errno) : myerror);
4430 printf(
" -- Running lua script %s\n", name);
4433 memset(myerror, 0x00, 200);
4436 if ((err =
lua_pcall(wsh->
L, 0, 0, 0) != 0)) {
4437 snprintf(myerror, 199,
"error %d : %s", err,
lua_strerror(err));
4438 fprintf(stderr,
"lua_pcall() failed with %s, for: %s (%s)\n",
lua_tostring(wsh->
L, -1), name, errno ? strerror(errno) : myerror);
4455 unsigned char sig[5];
4456 unsigned char validelf[4] =
"\177ELF";
4460 fd = open(fname, O_RDONLY);
4465 memset(sig, 0x00, 5);
4469 return strncmp(sig, validelf, 4) ? 0 : 1;
4478 unsigned int scriptcount = 0;
4479 DL_COUNT(wsh->
scripts, s, scriptcount);
4482 printf(
" -- running %u scripts\n", scriptcount);
4505 DL_FOREACH_SAFE(wsh->
scripts, ss, stmp) {
4519 printf(
"\n%s[FATAL]\tInterrupted too many times : exiting%s\n",
RED,
NORMAL);
4520 _Exit(EXIT_FAILURE);
4544 printf(
"argument[%u]: %s\n", j, wsh->
script_args[j]);
4556 s = calloc(1,
sizeof(
struct script_t));
4557 s->
name = strdup(name);
4571 p = calloc(1,
sizeof(
struct preload_t));
4572 p->
name = strdup(name);
4583 struct link_map *handle;
4584 unsigned long int ret = 0;
4587 printf(
" * Preloading : %s\n", libname);
4590 handle = dlopen(libname, RTLD_NOW);
4592 fprintf(stderr,
"ERROR: %s\n", dlerror());
4597 printf(
" -- Base address: %p of %s\n", (
void *) handle->l_addr, libname);
4613 DL_COUNT(wsh->
preload, p, count);
4616 printf(
" -- Preloading %u binaries\n", count);
4619 DL_FOREACH_SAFE(wsh->
preload, p, tmp) {
4631 const char *short_opt =
"hxvV";
4636 struct option long_opt[] = {
4637 {
"help", no_argument, NULL,
'h'},
4638 {
"args", no_argument, NULL,
'x'},
4639 {
"verbose", no_argument, NULL,
'v'},
4640 {
"version", no_argument, NULL,
'V'},
4646 printf(
"ERROR: not enough arguments !\nTry --help for help.\n");
4647 _Exit(EXIT_FAILURE);
4652 while ((c = getopt_long(argc, argv, short_opt, long_opt, NULL)) != -1) {
4661 _Exit(EXIT_SUCCESS);
4670 _Exit(EXIT_SUCCESS);
4678 fprintf(stderr,
"%s: invalid option -- %c\n", argv[0], c);
4679 fprintf(stderr,
"Try `%s --help' for more information.\n", argv[0]);
4680 _Exit(EXIT_FAILURE);
4686 if (count >= argc - 1) {
4690 for (i = count + 1; i < argc; i++) {
4692 if (!strncmp(argv[i],
"-x", strlen(argv[i]))) {
4696 }
else if (!stat(argv[i], &sb)) {
4699 printf(
" * adding binary %s to queue\n", argv[i]);
4704 printf(
" * adding script %s to queue\n", argv[i]);
4722 printf(
"%s version:%s (%s %s)\n", WNAME, WVERSION, WTIME, WDATE);
4731 printf(
"Usage: %s [script] [options] [binary1] [binary2] ... [-x] [script_arg1] [script_arg2] ...\n", name);
4733 printf(
"Options:\n\n");
4734 printf(
" -x, --args Optional script argument separator.\n");
4735 printf(
" -v, --verbose\n");
4736 printf(
" -V, --version\n");
4738 printf(
"Script:\n\n");
4739 printf(
" If the first argument is an existing file which is not a known binary file format,\n");
4740 printf(
" it is assumed to be a lua script and gets executed.\n");
4742 printf(
"Binaries:\n\n");
4743 printf(
" Any binary file name before the -x tag gets loaded before running the script.\n");
4744 printf(
" The last binary loaded is the main binary analyzed.\n");
4765 if(addr == NULL){
return 0; }
4766 if((
unsigned long int)addr < 4096){
return 0; }
4786 if(addr == NULL){
return 0; }
4787 if((
unsigned long int)addr < 4096){ printf(
"ERROR: Write to first page forbidden\n");
return 0; }
4789 memmove(addr, data, len);
4801 if(addr == NULL){
return 0; }
4802 if((
unsigned long int)addr < 4096){ printf(
"ERROR: Read first page forbidden\n");
return 0; }
4812 struct rusage usage;
4813 getrusage(RUSAGE_SELF,&usage);
4815 printf(
" %s, %li\n",
" maximum resident set size " , usage.ru_maxrss );
4816 printf(
" %s, %li\n",
" page reclaims " , usage.ru_minflt );
4817 printf(
" %s, %li\n",
" block input operations " , usage.ru_inblock );
4818 printf(
" %s, %li\n",
" block output operations " , usage.ru_oublock );
4819 printf(
" %s, %li\n",
" voluntary context switches " , usage.ru_nvcsw );
4820 printf(
" %s, %li\n",
" involuntary context switches " , usage.ru_nivcsw );
4822 printf(
"Memory usage: %ld Kb\n",usage.ru_maxrss);
4834 unsigned long int len = 0;
int scan_sections(char *fname, unsigned long int baseaddr)
unsigned int trace_singlebranch
int wsh_print_version(void)
int execlib(lua_State *L)
int rawmemstr(lua_State *L)
int getcharbuf(lua_State *L)
unsigned int read_elf_sig(char *fname, struct stat *sb)
struct script_t * scripts
void singlebranch(lua_State *L)
int gencore(lua_State *L)
int sort_learnt(learn_t *a, learn_t *b)
#define lua_pushcfunction(L, f)
void declare_internals(void)
LUA_API void() lua_pushinteger(lua_State *L, lua_Integer n)
void rtrace(lua_State *L)
unsigned int trace_strace
void declare_num(int val, char *name)
unsigned int globalsignals
unsigned long long int singlebranch_hash
void untraceunaligned(lua_State *L)
void segment_add(unsigned long int addr, unsigned long int size, char *perms, char *fname, char *ptype, int flags)
int phdr_cmp(segments_t *a, segments_t *b)
void unset_branch_flag(void)
LUA_API const char *() lua_pushstring(lua_State *L, const char *s)
void btr_enable(int procnum)
int linenoiseHistoryAdd(const char *line)
struct symbols_t * symbols
void unrtrace(lua_State *L)
int print_objects(lua_State *L)
void unverbosetrace(lua_State *L)
int bsspolute(lua_State *L)
unsigned int longjmp_ptr_high_cnt
void hexdump(uint8_t *data, size_t size, size_t colorstart, size_t color_len)
LUA_API int() lua_isuserdata(lua_State *L, int idx)
int printarg(unsigned long int val)
int linenoiseHistorySave(const char *filename)
LUALIB_API void() luaL_openlibs(lua_State *L)
void linenoiseSetCompletionCallback(linenoiseCompletionCallback *)
#define DEFAULT_SCRIPT_INDEX
void completion(const char *buf, linenoiseCompletions *lc)
struct sections_t * shdrs
void unsystrace(lua_State *L)
int run_shell(lua_State *L)
void inthandler(int signal, siginfo_t *s, void *u)
void entry_point_add(unsigned long int addr, char *fname)
char * decode_type(unsigned int type)
int phdr_callback(struct dl_phdr_info *info, size_t size, void *data)
int hollywood(lua_State *L)
unsigned int trace_rtrace
unsigned int ltrace(void)
int scan_symbol(char *symbol, char *libname)
LUA_API void() lua_pushnumber(lua_State *L, lua_Number n)
LUA_API int() lua_isstring(lua_State *L, int idx)
#define lua_tonumber(L, i)
int priv_strcpy(lua_State *L)
unsigned int global_xalloc
int rawmemaddr(lua_State *L)
int ptoh(int perms, char hperms[])
char * decode_flags(unsigned int flags)
int prototypes(lua_State *L)
void linenoiseAddCompletion(linenoiseCompletions *, const char *)
int setcharbuf(lua_State *L)
int add_binary_preload(char *name)
void traphandler(int signal, siginfo_t *s, void *ptr)
int breakpoint(lua_State *L)
#define SHELL_HISTORY_NAME
LUA_API void *() lua_touserdata(lua_State *L, int idx)
void btr_disable(int procnum)
#define luaL_loadbuffer(L, s, sz, n)
#define luaL_loadfile(L, f)
int linenoiseHistoryLoad(const char *filename)
void systrace(lua_State *L)
int do_loadlib(char *libname)
void section_add(unsigned long int addr, unsigned long int size, char *libname, char *name, char *perms, int flags)
int set_sighandlers(void)
void scan_syms(char *dynstr, Elf_Sym *sym, unsigned long int sz, char *libname)
void print_backtrace(void)
int disable_core(lua_State *L)
int entrypoints(lua_State *L)
char * linenoise(const char *prompt)
#define lua_pcall(L, n, r, f)
LUA_API void() lua_setglobal(lua_State *L, const char *name)
LUA_API void() lua_pushlightuserdata(lua_State *L, void *p)
char * sicode_strerror(int signal, siginfo_t *s)
char * signaltoname(int signal)
LUA_API void() lua_settable(lua_State *L, int idx)
unsigned int trace_singlestep
int rawmemwrite(lua_State *L)
int rawmemstrlen(lua_State *L)
int print_symbols(lua_State *L)
void parse_dyn(struct link_map *map)
void declare_func(void *addr, char *name)
struct lua_State lua_State
LUA_API int() lua_isnumber(lua_State *L, int idx)
void set_branch_flag(void)
int verbose(lua_State *L)
int add_script_arguments(int argc, char **argv, unsigned int i)
int print_procmap(unsigned int pid)
int enable_core(lua_State *L)
unsigned long long int init
sections_t * section_from_addr(unsigned long int addr)
LUALIB_API lua_State *() luaL_newstate(void)
int alloccharbuf(lua_State *L)
int wsh_usage(char *name)
#define DEFAULT_LEARN_FILE
unsigned int singlestep_count
void singlestep(lua_State *L)
void unsinglestep(lua_State *L)
LUA_API int() lua_getglobal(lua_State *L, const char *name)
int lua_strerror(int err)
int wsh_getopt(wsh_t *wsh1, int argc, char **argv)
int libcall(lua_State *L)
unsigned int opt_hollywood
void unset_align_flag(void)
segments_t * segment_from_addr(unsigned long int addr)
void sighandler(int signal, siginfo_t *s, void *ptr)
void fatal_error(lua_State *L, char *msg)
unsigned long long int sigbus_hash
unsigned int is_stdinscript
LUA_API lua_CFunction() lua_tocfunction(lua_State *L, int idx)
struct segments_t * phdrs
int rawmemusage(lua_State *L)
LUA_API int() lua_getfield(lua_State *L, int idx, const char *k)
void affinity(int procnum)
unsigned long long int max
LUA_API void() lua_pushvalue(lua_State *L, int idx)
int add_symbol(char *symbol, char *libname, char *htype, char *hbind, unsigned long value, unsigned int size, unsigned long int addr)
LUA_API int() lua_iscfunction(lua_State *L, int idx)
unsigned long int faultaddr
int detailed_help(char *name)
int learn_proto(unsigned long *arg, unsigned long int faultaddr, int reason)
void traceunaligned(lua_State *L)
#define lua_isfunction(L, n)
void set_trace_flag(void)
void unset_trace_flag(void)
int print_functions(lua_State *L)
char * cplus_demangle(const char *mangled, int options)
char * lua_default_functions[]
#define lua_tostring(L, i)
int grepptr(lua_State *L)
unsigned int trace_unaligned
LUA_API void() lua_settop(lua_State *L, int idx)
char * sicodetoname(int code)
void scan_section(Elf_Shdr *shdr, char *strTab, int shnum, char *fname, unsigned long int baseaddr)
LUA_API const char *() lua_pushlstring(lua_State *L, const char *s, size_t len)
void set_align_flag(void)
#define lua_call(L, n, r)
char * symbol_totype(int n)
void parse_link_map_dyn(struct link_map *map)
int print_libs(lua_State *L)
unsigned int opt_verbosetrace
int traceback(lua_State *L)
void verbosetrace(lua_State *L)
int headers(lua_State *L)
unsigned long int btcaller
int shdr_cmp(sections_t *a, sections_t *b)
void unsinglebranch(lua_State *L)
#define lua_istable(L, n)
int loadbin(lua_State *L)
LUA_API void() lua_close(lua_State *L)
int is_mapped(unsigned long int addr)
void info_function(void *addr)
unsigned int singlebranch_count
int linenoiseHistorySetMaxLen(int len)
char * symbol_tobind(int n)
sections_t * symbol_from_name(char *fname)
unsigned int script_argnum
sections_t * symbol_from_addr(unsigned long int addr)
void exit_group(int status)
LUA_API void() lua_createtable(lua_State *L, int narr, int nrec)
unsigned long long int singlestep_hash
struct learn_key_t learn_key_t
int shdr_callback(struct dl_phdr_info *info, size_t size, void *data)
unsigned long long int end
void bushandler(int signal, siginfo_t *s, void *ptr)
void alarmhandler(int signal, siginfo_t *s, void *u)
struct link_map * loadlibrary(char *libname)
struct preload_t * preload
unsigned int sigbus_count
int priv_memcpy(lua_State *L)
int add_script_exec(char *name)
int rawmemread(lua_State *L)
int priv_strcat(lua_State *L)
#define luaL_checkstring(L, n)
int run_script(char *name)