📄 gen.c
字号:
break; case 2: e_buf[offset++] = d.byte[0]; e_buf[offset++] = d.byte[1]; break; case 4: e_buf[offset++] = d.byte[0]; e_buf[offset++] = d.byte[1]; e_buf[offset++] = d.byte[2]; e_buf[offset++] = d.byte[3]; break; case 8: e_buf[offset++] = d.byte[0]; e_buf[offset++] = d.byte[1]; e_buf[offset++] = d.byte[2]; e_buf[offset++] = d.byte[3]; if (!is_SUPPORT_VALUE64(i_attr)) { fputs("warning: the instruction not support " "64-bit value, the 64-bit value cut to " "32-bit value\n", stderr); break; } e_buf[offset++] = d.byte[4]; e_buf[offset++] = d.byte[5]; e_buf[offset++] = d.byte[6]; e_buf[offset++] = d.byte[7]; break; } /* example: sub esp, 8 */ /* if (((OPTYPE(so_attr) == IMME) || (OPTYPE(so_attr) == IMME_1)) && (SIZE(so_attr) == SIZE8)) { set_imme = 0; }*/ /* example: "sub esp,8", "out 0x0c, eax" */ if ((SIZE(so_attr) == SIZE8) || (SIZE(do_attr) == SIZE8)) set_imme = 0; else set_imme = (ops_size >> 3) - imme_size; for (; set_imme; set_imme--) e_buf[offset++] = 0; if (u.code[0] == 0xc8) { /* It's Enter instruction */ /* example: enter 0x0c, 0x01 */ d.ll = do_key->imme->imme_value; if (get_sizeof(d.ll) == 1) { e_buf[offset++] = 0; e_buf[offset++] = d.byte[0]; } else if (get_sizeof(d.ll) == 2) { e_buf[offset++] = d.byte[0]; e_buf[offset++] = d.byte[1]; } } } /* end if(imme) */ return errno;}/********************************************************* * * function: do_transfer_gen(struct iob *e_buf, int adj) * **********************************************************/errno_t do_transfer_gen(struct iob *e_buf, int adj){ errno_t errno = 0; unsigned long long label_addr = 0; unsigned long long label_offset = 0; unsigned long long hole_addr = 0; o_key_t so_key = { 0, 0, 0 }; ops_key_t ops_key = { 0, 0, 0 }; ops_attr_t ops_attr = { 0, 0, 0 }; e_key_t e_key = { 0, 0, 0, 0, 0, 0, 0 }; imme_t imme; so_key.imme = &imme; ops_key.so_key = &so_key; char encode[15]; struct transfer_hole_struct *hole_node = hole_link; while (hole_node) { imme.imme_value = 0; imme.cast = 0; /* get label address via hole_node's label example: jmp @label. the mean is get @label's address with get_label_addr() */ current_bits = hole_node->bits; struct label_link *label_node = get_label_node(hole_node->hole_label); if (!label_node) { sprintf(err_msg, "at %d: %s\n", hole_node->hole_line, "transfer label error"); mount_err_link(0, 0, err_msg); return ERR_OPERAND; } hole_addr = hole_node->hole_addr; label_addr = label_node->label->addr; /* reserved: the label_offset = label_offset - HOLE_SIZE */ label_offset = hole_addr >= label_addr ? hole_addr - label_addr : label_addr - hole_addr; /* the mean is byte or dword or qword ? */ unsigned long long offset_size = get_sizeof(label_offset); if (offset_size == 0) { /* it's two bytes, jmp self !!!! so, it's operand's encode is 0xfe !!! example: @label: jmp @label */ imme.cast = 8; ops_attr.so_attr = IMME | SIZE8; } else if (offset_size == 1) { /* the offset size is byte example: jmp 0xc */ unsigned char c_off = label_addr - hole_addr; imme.imme_value = (long long)c_off; imme.cast = 8; if (label_offset > 0x7f) { if (current_bits == 16) ops_attr.so_attr |= SIZE16; else if (current_bits == 32) ops_attr.so_attr |= SIZE32; else if (current_bits == 64) ops_attr.so_attr |= SIZE64; } else ops_attr.so_attr |= SIZE8; ops_attr.so_attr |= IMME; } else if ((offset_size == 8) && (current_bits == 64)) { /* the offset size is qword in 64-bit mode example: jmp 0x1122334455667788 */ unsigned long long ll_off = label_addr - hole_addr; imme.imme_value = (long long)ll_off; imme.cast = 64; ops_attr.so_attr = IMME | SIZE64; } else if (offset_size == 2) { /* else all the offset size is dword example: jmp 0x08040010 */ if (current_bits == 16) { unsigned short s_off = label_addr - hole_addr; imme.imme_value = (long long)s_off; imme.cast = 16; ops_attr.so_attr = IMME | SIZE16; } else { unsigned int i_off = label_addr - hole_addr; imme.imme_value = (long long)i_off; imme.cast = 32; ops_attr.so_attr = IMME | SIZE32; } } else if ((offset_size == 4) && (current_bits == 32)) { unsigned int i_off = label_addr - hole_addr; imme.imme_value = (long long)i_off; imme.cast = 32; ops_attr.so_attr = IMME | SIZE32; } else { sprintf(err_msg, "at %d: %s", "transfer instruct label size error!"); mount_err_link(0, 0, err_msg); return ERR_OPERAND; } e_key.ops_key = &ops_key; /* the hole_i_key is "jmp" , "call" or "jz", so that */ e_key.i_key = get_i_key(hole_node->hole_i_key, &ops_attr); if (!e_key.i_key) { /* no found */ sprintf(err_msg, "error: invalid instruction " "or operand\n"); mount_err_link(0, 0, err_msg); return ERR_INS; } if (e_key.i_key->i_attr & FS_IN_BITS) { if (current_bits == 16) { short w_off = label_addr - hole_addr; imme.imme_value = (long long)w_off; } else if (current_bits == 32) { int i_off = label_addr - hole_addr; imme.imme_value = (long long)i_off; } else if (current_bits == 64) { long long ll_off = label_addr - hole_addr; imme.imme_value = (long long)ll_off; } imme.cast = current_bits; } if (adj == 1) { /* frist adjust offset size of between label and hole */ if (label_addr <= hole_addr) imme.imme_value -= hole_node->hole_size; } else { /* again adjust offset size of between label and hole */ /* **** do not adjust offset size ****** the this case: the adj value is 0 !!!! */ imme.imme_value -= hole_node->hole_size; } do_generate(encode, &e_key); int adj_size = hole_node->hole_size - offset; if (adj && adj_size) { /**** adjust label link *****/ struct label_link* head_ll = label_table; for (; head_ll; head_ll = head_ll->next) if (head_ll->label->addr > hole_addr) head_ll->label->addr -= adj_size; /***** adjust hole link *****/ struct transfer_hole_struct *hole_next = hole_node->next; for (; hole_next; hole_next = hole_next->next) hole_next->hole_addr -= adj_size; mem_copy(&e_buf->buf[hole_addr + offset], &e_buf->buf[hole_addr + hole_node->hole_size], current_pc - hole_addr - hole_node->hole_size); current_pc -= adj_size; hole_node->hole_size = offset; } if (!adj) mem_copy(&e_buf->buf[hole_addr], encode, offset); hole_node = hole_node->next; } return errno;}/********************************************* do_imul_gen(char *e_buf, e_key_t *e_key)*********************************************/errno_t do_imul_gen(char *e_buf, e_key_t *e_key){ errno_t errno = 0; if (!e_buf || !e_key) return ERR_INS; return errno;}/********************************************************** function generate(char *e_buf, e_key_t *e_key) parameter: e_buf: this is encodes memory buffer. e_key: this is instruction encode key word link. return: 0 if successed. errno if failed.**********************************************************/errno_t generate(struct iob *e_buffer) { errno_t errno = 0; int i = 0; e_key_t *e_key = e_key_link; if (!e_buffer) return ERR_ERROR; unsigned char encode[15]; e_key_t *head_e_key = e_key; struct transfer_hole_struct *head_hl = hole_link; struct label_link *head_ll = label_table; int begin_line = 0; int end_line = 0; if (e_key) { if (head_hl) begin_line = e_key->line <= head_hl->hole_line ? e_key->line : head_hl->hole_line; else begin_line = e_key->line; if (head_ll) begin_line = begin_line <= head_ll->label->line ? begin_line : head_ll->label->line; end_line = line; } if (!e_key) { /* only hole_link or have nothing */ /* adjust hole link and label table addr */ for (i = begin_line; i <= end_line; i++) { if (head_ll && (i == head_ll->label->line)) { head_ll->label->addr = current_pc; head_ll = head_ll->next; } if (head_hl && (i == head_hl->hole_line)) { current_bits = head_hl->bits; head_hl->hole_addr = current_pc; if (current_bits == 16) head_hl->hole_size = 4; else if (current_bits == 32) head_hl->hole_size = 6; else if (current_bits == 64) head_hl->hole_size = 10; current_pc += head_hl->hole_size; head_hl = head_hl->next; } } } else for (i = begin_line; i <= end_line; i++) { unsigned long long prev_pc = current_pc; /* get label's address */ if (head_ll && i == head_ll->label->line) { head_ll->label->addr = current_pc; head_ll = head_ll->next; } /* get hole_link's address */ if (head_hl && (i == head_hl->hole_line)) { current_bits = head_hl->bits; head_hl->hole_addr = current_pc; if (current_bits == 16) { head_hl->hole_size = 4; } else if (current_bits == 32) { head_hl->hole_size = 6; } else if (current_bits == 64) { head_hl->hole_size = 10; } current_pc += head_hl->hole_size; head_hl = head_hl->next; } else if (e_key && (i == e_key->line)) { current_bits = e_key->bits; errno = do_generate(encode, e_key); current_pc += offset; e_key->current_pc = current_pc; e_key->length = offset - 1; e_key = e_key->next; } unsigned long e_len = current_pc - prev_pc; if (get_free_bytes(e_buffer) < e_len) flush_all_iob(e_buffer); write_into_iob(e_buffer, encode, e_len); } if (hole_link) { /* follow step adjust for all hole_struct and label_link */ errno = do_transfer_gen(e_buffer, 1); if (!errno) { /* finally adjust for all transfer instructions get right encode !!!! */ errno = do_transfer_gen(e_buffer, 2); } if (!errno) errno = do_transfer_gen(e_buffer, 0); } e_buffer->cnt = current_pc; e_buffer->tail_ptr = e_buffer->buf + current_pc; print_hole_link();print_label_table(); return errno;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -