-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathadd_shellcode.c
More file actions
108 lines (83 loc) · 3.39 KB
/
add_shellcode.c
File metadata and controls
108 lines (83 loc) · 3.39 KB
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#include "sigsleeper.h"
/**********************************************************************************************************************
*
* int add_shellcode(struct ptrace_pokedata *shellcode, char *buffer)
*
* Input:
* A pointer to the ptrace_pokedata structure where you want the translated shellcode stored.
* A string of hex characters representing the shellcode.
*
* Output:
* A return code.
* The translated shellcode (in the ptrace_pokedata structure).
*
* Purpose:
* Translate shellcode into a form that is ready for being injected into a remote process with a PTRACE_POKEDATA
* call. We do this in a manor that takes a little bit extra work up front, but ensures a minimum amount of time
* between the PTRACE_ATTACH and PTRACE_DETACH calls.
*
* Limitations:
* The buffer passed as input needs to have an even number of hex characters and be null terminated. Also, we
* assume that the filtering out of non-hex characters already happened when the buffer was being filled.
*
**********************************************************************************************************************/
int add_shellcode(struct ptrace_pokedata *shellcode, char *buffer){
int buffer_index;
struct data_node *this, *tmp;
char translation_buffer[BYTES_PER_WORD];
int translation_buffer_index;
// Each shellcode entry is a string made from two chars plus one null.
char hex_str[3];
int hex_str_index;
translation_buffer_index = 0;
memset(&translation_buffer, 0, sizeof(translation_buffer));
// First time through? Lets setup the initial state.
if(!shellcode->head){
if((shellcode->head = (struct data_node *) calloc(1, sizeof(struct data_node))) == NULL){
if(global_debug){
fprintf(stderr, "%s: add_shellcode(): calloc(1, %d): %s\n", program_invocation_short_name, (int) sizeof(struct data_node), strerror(errno));
}
return(-1);
}
shellcode->tail = shellcode->head;
this = shellcode->tail;
shellcode->node_count = 1;
// We've been called for this list before. Let's restore the state and head on in.
}else{
memcpy(translation_buffer, &(shellcode->tail->ptrace_word), sizeof(shellcode->tail->ptrace_word));
translation_buffer_index = shellcode->tail_index;
this = shellcode->tail;
}
hex_str_index = 0;
memset(&hex_str, 0, 3);
buffer_index = 0;
while(buffer[buffer_index]){
if(translation_buffer_index == sizeof(translation_buffer)){
memset(&translation_buffer, 0, sizeof(translation_buffer));
translation_buffer_index = 0;
if((tmp = (struct data_node *) calloc(1, sizeof(struct data_node))) == NULL){
if(global_debug){
fprintf(stderr, "%s: add_shellcode(): calloc(1, %d): %s\n", program_invocation_short_name, (int) sizeof(struct data_node), strerror(errno));
}
return(-1);
}
this->next = tmp;
this = tmp;
shellcode->node_count++;
}
hex_str[hex_str_index] = buffer[buffer_index++];
if(hex_str_index){
*(translation_buffer + translation_buffer_index++) = strtol(hex_str, NULL, 16);
if(translation_buffer_index == sizeof(translation_buffer)){
memcpy(&(this->ptrace_word), translation_buffer, sizeof(this->ptrace_word));
}
}
hex_str_index = (hex_str_index + 1) % 2;
}
if(translation_buffer_index != sizeof(translation_buffer)){
memcpy(&(this->ptrace_word), translation_buffer, sizeof(this->ptrace_word));
}
shellcode->tail = this;
shellcode->tail_index = translation_buffer_index;
return(0);
}