-
Notifications
You must be signed in to change notification settings - Fork 65
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added in initial draft of access write (modification) functions for s…
…ections, segments, and symbols, added several basic accessor functions and elf_symbol_count, elf_section_count, elf_segment_count, elf_dynsym_count
- Loading branch information
Showing
11 changed files
with
792 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
# General notes | ||
|
||
``` | ||
It is often times desirable to modify certain ELF structures, however it breaks the | ||
convention of using the API when directly accessing the ELF structures from the | ||
elfobj_t struct which is meant to be an opaque type. There are now accessor write | ||
functions for modifying symbol table entries, segment entries, and section header | ||
entries. In the future we will add the ability to modify other areas as well such | ||
as notes, dynamic segment, etc. | ||
Do not confuse these accessors with the soon to be merged instrumentation API functions | ||
that @ulexec is adding into the code base, however these accessor write functions are | ||
used by that code on the back-end. | ||
Please see examples/modify_*.c and read the comments as well for caveats. This will show | ||
you how to modify a given structure. Often times structures will be modified by index, | ||
and within the body of an iterator function. Every iterator has an index value; make sure | ||
to use index - 1, when modifying an object. For example: | ||
/* | ||
* Demonstrates how to modify symbol entries in .symtab | ||
* where we modify each entries st_value member. | ||
*/ | ||
#define _GNU_SOURCE | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <elf.h> | ||
#include <sys/types.h> | ||
#include <search.h> | ||
#include <sys/time.h> | ||
#include <string.h> | ||
#include "../include/libelfmaster.h" | ||
int main(int argc, char **argv) | ||
{ | ||
elfobj_t obj; | ||
elf_error_t error; | ||
elf_dynsym_iterator_t ds_iter; | ||
elf_symtab_iterator_t sm_iter; | ||
struct elf_symbol symbol; | ||
if (argc < 2) { | ||
printf("Usage: %s <binary>\n", argv[0]); | ||
exit(EXIT_SUCCESS); | ||
} | ||
if (elf_open_object(argv[1], &obj, | ||
ELF_LOAD_F_STRICT|ELF_LOAD_F_MODIFY, &error) == false) { | ||
fprintf(stderr, "%s\n", elf_error_msg(&error)); | ||
return -1; | ||
} | ||
elf_symtab_iterator_init(&obj, &sm_iter); | ||
while (elf_symtab_iterator_next(&sm_iter, &symbol) == ELF_ITER_OK) { | ||
struct elf_symbol sym; | ||
printf("%s: %#lx-%#lx\n",symbol.name, symbol.value, | ||
symbol.value + symbol.size); | ||
memcpy(&sym, &symbol, sizeof(struct elf_symbol)); | ||
sym.value = 0xdeadbeef; | ||
if (elf_symtab_modify(&obj, sm_iter.index - 1, &sym, &error) == false) { | ||
printf("Failed to modify elf symbol table: %s\n", elf_error_msg(&error)); | ||
} | ||
} | ||
/* | ||
* NOTE: commit cannot be called inside of the symtab iterator, | ||
* this will be fixed in the future. | ||
*/ | ||
elf_symtab_commit(&obj); | ||
elf_symtab_iterator_init(&obj, &sm_iter); | ||
printf("After .symtab modification\n"); | ||
while (elf_symtab_iterator_next(&sm_iter, &symbol) == ELF_ITER_OK) { | ||
struct elf_symbol sym; | ||
printf("%s: %#lx-%#lx\n",symbol.name, symbol.value, | ||
symbol.value + symbol.size); | ||
} | ||
elf_close_object(&obj); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/* | ||
*/ | ||
|
||
#define _GNU_SOURCE | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <elf.h> | ||
#include <sys/types.h> | ||
#include <search.h> | ||
#include <sys/time.h> | ||
#include "../include/libelfmaster.h" | ||
|
||
int main(int argc, char **argv) | ||
{ | ||
elfobj_t obj; | ||
elf_error_t error; | ||
struct elf_symbol symbol; | ||
|
||
if (argc < 2) { | ||
printf("Usage: %s <binary>\n", argv[0]); | ||
exit(EXIT_SUCCESS); | ||
} | ||
if (elf_open_object(argv[1], &obj, | ||
ELF_LOAD_F_SMART|ELF_LOAD_F_FORENSICS, &error) == false) { | ||
fprintf(stderr, "%s\n", elf_error_msg(&error)); | ||
return -1; | ||
} | ||
if (elf_flags(&obj, ELF_SCOP_F) == true) { | ||
printf("SCOP binary\n"); | ||
} | ||
ssize_t ret = elf_scop_text_filesz(&obj); | ||
printf("ret: %zu\n", ret); | ||
if (ret > 0) { | ||
printf("Total text segment size: %lu bytes\n", ret); | ||
} | ||
printf("elf_executable_text_base: %lx offset: %lx\n", elf_executable_text_base(&obj), | ||
elf_executable_text_offset(&obj)); | ||
elf_close_object(&obj); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/* | ||
* Demonstrates how to modify every dynamic symbol table | ||
* entry, where we modify the st_value's. | ||
*/ | ||
|
||
#define _GNU_SOURCE | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <elf.h> | ||
#include <sys/types.h> | ||
#include <search.h> | ||
#include <sys/time.h> | ||
#include <string.h> | ||
#include "../include/libelfmaster.h" | ||
|
||
int main(int argc, char **argv) | ||
{ | ||
elfobj_t obj; | ||
elf_error_t error; | ||
elf_dynsym_iterator_t ds_iter; | ||
struct elf_symbol symbol; | ||
|
||
if (argc < 2) { | ||
printf("Usage: %s <binary>\n", argv[0]); | ||
exit(EXIT_SUCCESS); | ||
} | ||
if (elf_open_object(argv[1], &obj, | ||
ELF_LOAD_F_STRICT|ELF_LOAD_F_MODIFY, &error) == false) { | ||
fprintf(stderr, "%s\n", elf_error_msg(&error)); | ||
return -1; | ||
} | ||
elf_dynsym_iterator_init(&obj, &ds_iter); | ||
while (elf_dynsym_iterator_next(&ds_iter, &symbol) == ELF_ITER_OK) { | ||
struct elf_symbol sym; | ||
|
||
printf("%s: %#lx-%#lx\n",symbol.name, symbol.value, | ||
symbol.value + symbol.size); | ||
memcpy(&sym, &symbol, sizeof(struct elf_symbol)); | ||
sym.value = 0xdeadbeef; | ||
/* | ||
* NOTE use iter.index - 1, otherwise it will not hit sym[0] and will | ||
* eventually go out of bounds. | ||
*/ | ||
if (elf_dynsym_modify(&obj, ds_iter.index - 1, &sym, &error) == false) { | ||
printf("Failed to modify elf symbol table: %s\n", elf_error_msg(&error)); | ||
} | ||
} | ||
/* | ||
* commit cannot be called inside of the dynsym iterator | ||
*/ | ||
elf_dynsym_commit(&obj); | ||
elf_dynsym_iterator_init(&obj, &ds_iter); | ||
printf("After .dynsym modification\n"); | ||
while (elf_dynsym_iterator_next(&ds_iter, &symbol) == ELF_ITER_OK) { | ||
struct elf_symbol sym; | ||
|
||
printf("%s: %#lx-%#lx\n",symbol.name, symbol.value, | ||
symbol.value + symbol.size); | ||
} | ||
|
||
elf_close_object(&obj); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/* | ||
* Demonstrates how we modify the sh_addr of the .text section | ||
*/ | ||
|
||
#define _GNU_SOURCE | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <elf.h> | ||
#include <sys/types.h> | ||
#include <search.h> | ||
#include <sys/time.h> | ||
#include <string.h> | ||
#include "../include/libelfmaster.h" | ||
|
||
int main(int argc, char **argv) | ||
{ | ||
elfobj_t obj; | ||
elf_error_t error; | ||
elf_section_iterator_t iter; | ||
struct elf_section section; | ||
|
||
if (argc < 2) { | ||
printf("Usage: %s <binary>\n", argv[0]); | ||
exit(EXIT_SUCCESS); | ||
} | ||
if (elf_open_object(argv[1], &obj, | ||
ELF_LOAD_F_STRICT|ELF_LOAD_F_MODIFY, &error) == false) { | ||
fprintf(stderr, "%s\n", elf_error_msg(&error)); | ||
return -1; | ||
} | ||
elf_section_iterator_init(&obj, &iter); | ||
while (elf_section_iterator_next(&iter, §ion) == ELF_ITER_OK) { | ||
struct elf_section s; | ||
|
||
if (strcmp(section.name, ".text") == 0) { | ||
memcpy(&s, §ion, sizeof(s)); | ||
s.address = 0xdeadbeef; | ||
elf_section_modify(&obj, iter.index - 1, &s, &error); | ||
} | ||
} | ||
/* | ||
* Technically you can call this within the elf_section_iterator_next body, | ||
* whereas with elf_symtab/dynsym_modify you cannot. But it makes sense to | ||
* call it after you have made all of your changes because it is fairly | ||
* expensive. | ||
*/ | ||
elf_section_commit(&obj); | ||
elf_section_by_name(&obj, ".text", §ion); | ||
printf("text section modified to sh_addr of: %#lx\n", section.address); | ||
/* | ||
* Unlike elf_section/elf_symtab/elf_dynsym modify, with elf_segment | ||
* modify we do not need to call a commit function because we don't | ||
* keep any internal abstract representations of the segments. | ||
* so we can just close the object and be done. | ||
*/ | ||
elf_close_object(&obj); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
/* | ||
* Demonstrates how we modify the p_vaddr of the first LOAD segment. | ||
*/ | ||
|
||
#define _GNU_SOURCE | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <elf.h> | ||
#include <sys/types.h> | ||
#include <search.h> | ||
#include <sys/time.h> | ||
#include <string.h> | ||
#include "../include/libelfmaster.h" | ||
|
||
int main(int argc, char **argv) | ||
{ | ||
elfobj_t obj; | ||
elf_error_t error; | ||
elf_segment_iterator_t iter; | ||
struct elf_segment segment; | ||
|
||
if (argc < 2) { | ||
printf("Usage: %s <binary>\n", argv[0]); | ||
exit(EXIT_SUCCESS); | ||
} | ||
if (elf_open_object(argv[1], &obj, | ||
ELF_LOAD_F_STRICT|ELF_LOAD_F_MODIFY, &error) == false) { | ||
fprintf(stderr, "%s\n", elf_error_msg(&error)); | ||
return -1; | ||
} | ||
elf_segment_iterator_init(&obj, &iter); | ||
while (elf_segment_iterator_next(&iter, &segment) == ELF_ITER_OK) { | ||
if (segment.offset == 0) { | ||
struct elf_segment s; | ||
|
||
memcpy(&s, &segment, sizeof(segment)); | ||
s.vaddr = 0xdeadbeef; | ||
elf_segment_modify(&obj, iter.index - 1, &s, &error); | ||
} | ||
} | ||
/* | ||
* Unlike elf_section/elf_symtab/elf_dynsym modify, with elf_segment | ||
* modify we do not need to call a commit function because we don't | ||
* keep any internal abstract representations of the segments. | ||
* so we can just close the object and be done. | ||
*/ | ||
elf_close_object(&obj); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/* | ||
* Demonstrates how to modify symbol entries in .symtab | ||
* where we modify each entries st_value member. | ||
*/ | ||
|
||
#define _GNU_SOURCE | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <elf.h> | ||
#include <sys/types.h> | ||
#include <search.h> | ||
#include <sys/time.h> | ||
#include <string.h> | ||
#include "../include/libelfmaster.h" | ||
|
||
int main(int argc, char **argv) | ||
{ | ||
elfobj_t obj; | ||
elf_error_t error; | ||
elf_dynsym_iterator_t ds_iter; | ||
elf_symtab_iterator_t sm_iter; | ||
struct elf_symbol symbol; | ||
|
||
if (argc < 2) { | ||
printf("Usage: %s <binary>\n", argv[0]); | ||
exit(EXIT_SUCCESS); | ||
} | ||
if (elf_open_object(argv[1], &obj, | ||
ELF_LOAD_F_STRICT|ELF_LOAD_F_MODIFY, &error) == false) { | ||
fprintf(stderr, "%s\n", elf_error_msg(&error)); | ||
return -1; | ||
} | ||
elf_symtab_iterator_init(&obj, &sm_iter); | ||
while (elf_symtab_iterator_next(&sm_iter, &symbol) == ELF_ITER_OK) { | ||
struct elf_symbol sym; | ||
|
||
printf("%s: %#lx-%#lx\n",symbol.name, symbol.value, | ||
symbol.value + symbol.size); | ||
memcpy(&sym, &symbol, sizeof(struct elf_symbol)); | ||
sym.value = 0xdeadbeef; | ||
if (elf_symtab_modify(&obj, sm_iter.index - 1, &sym, &error) == false) { | ||
printf("Failed to modify elf symbol table: %s\n", elf_error_msg(&error)); | ||
} | ||
} | ||
/* | ||
* NOTE: commit cannot be called inside of the symtab iterator, | ||
* this will be fixed in the future, however it will incurr overhead | ||
* to call after each symbol modification, but it may at times be | ||
* desirable in some edge cases. | ||
*/ | ||
elf_symtab_commit(&obj); | ||
elf_symtab_iterator_init(&obj, &sm_iter); | ||
printf("After .symtab modification\n"); | ||
while (elf_symtab_iterator_next(&sm_iter, &symbol) == ELF_ITER_OK) { | ||
struct elf_symbol sym; | ||
|
||
printf("%s: %#lx-%#lx\n",symbol.name, symbol.value, | ||
symbol.value + symbol.size); | ||
} | ||
|
||
elf_close_object(&obj); | ||
} |
Oops, something went wrong.