From e36d15da613aae1a0bd6245b8cc23c3ac5ebf95f Mon Sep 17 00:00:00 2001 From: lpouzenc Date: Sat, 7 Sep 2013 19:19:32 +0200 Subject: Tout le reverse est regroupe a present. Manque le makefile car .gitignore un peu violent --- .gitignore | 2 +- reverse-engineering/dosbox_snif/dos_lemm.h | 132 +++++++++++ reverse-engineering/dosbox_snif/int16todec.c | 9 + reverse-engineering/dosbox_snif/main_dump.c | 39 ++++ reverse-engineering/dosbox_snif/main_dump_delta.c | 182 +++++++++++++++ reverse-engineering/dosbox_snif/main_dump_ds0.c | 61 ++++++ reverse-engineering/dosbox_snif/main_poke.c | 64 ++++++ .../dosbox_snif/main_validate_code.c | 12 + reverse-engineering/dosbox_snif/rsp.c | 243 +++++++++++++++++++++ reverse-engineering/dosbox_snif/rsp.h | 27 +++ reverse-engineering/dosbox_snif/rsp_lemm.c | 65 ++++++ reverse-engineering/dosbox_snif/rsp_lemm.h | 13 ++ reverse-engineering/dosbox_snif/utils.c | 112 ++++++++++ reverse-engineering/dosbox_snif/utils.h | 11 + reverse-engineering/work/seg_code_0208.txt | 30 +-- src/dosbox_snif/dos_lemm.h | 108 --------- src/dosbox_snif/int16todec.c | 9 - src/dosbox_snif/main_dump.c | 39 ---- src/dosbox_snif/main_dump_delta.c | 182 --------------- src/dosbox_snif/main_dump_ds0.c | 61 ------ src/dosbox_snif/main_poke.c | 64 ------ src/dosbox_snif/rsp.c | 243 --------------------- src/dosbox_snif/rsp.h | 27 --- src/dosbox_snif/rsp_lemm.c | 65 ------ src/dosbox_snif/rsp_lemm.h | 13 -- src/dosbox_snif/utils.c | 112 ---------- src/dosbox_snif/utils.h | 11 - 27 files changed, 986 insertions(+), 950 deletions(-) create mode 100644 reverse-engineering/dosbox_snif/dos_lemm.h create mode 100644 reverse-engineering/dosbox_snif/int16todec.c create mode 100644 reverse-engineering/dosbox_snif/main_dump.c create mode 100644 reverse-engineering/dosbox_snif/main_dump_delta.c create mode 100644 reverse-engineering/dosbox_snif/main_dump_ds0.c create mode 100644 reverse-engineering/dosbox_snif/main_poke.c create mode 100644 reverse-engineering/dosbox_snif/main_validate_code.c create mode 100644 reverse-engineering/dosbox_snif/rsp.c create mode 100644 reverse-engineering/dosbox_snif/rsp.h create mode 100644 reverse-engineering/dosbox_snif/rsp_lemm.c create mode 100644 reverse-engineering/dosbox_snif/rsp_lemm.h create mode 100644 reverse-engineering/dosbox_snif/utils.c create mode 100644 reverse-engineering/dosbox_snif/utils.h delete mode 100644 src/dosbox_snif/dos_lemm.h delete mode 100644 src/dosbox_snif/int16todec.c delete mode 100644 src/dosbox_snif/main_dump.c delete mode 100644 src/dosbox_snif/main_dump_delta.c delete mode 100644 src/dosbox_snif/main_dump_ds0.c delete mode 100644 src/dosbox_snif/main_poke.c delete mode 100644 src/dosbox_snif/rsp.c delete mode 100644 src/dosbox_snif/rsp.h delete mode 100644 src/dosbox_snif/rsp_lemm.c delete mode 100644 src/dosbox_snif/rsp_lemm.h delete mode 100644 src/dosbox_snif/utils.c delete mode 100644 src/dosbox_snif/utils.h diff --git a/.gitignore b/.gitignore index 6240c8d..4f95be9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ # autoreconf && configure stuff INSTALL -Makefile +/Makefile Makefile.in aclocal.m4 autom4te.cache/ diff --git a/reverse-engineering/dosbox_snif/dos_lemm.h b/reverse-engineering/dosbox_snif/dos_lemm.h new file mode 100644 index 0000000..f6c7c95 --- /dev/null +++ b/reverse-engineering/dosbox_snif/dos_lemm.h @@ -0,0 +1,132 @@ +#ifndef _DOS_LEMM_H +#define _DOS_LEMM_H + + +struct _state { + uint8_t s_splatting:1; //0x01 + uint8_t s_exploding:1; //0x02 combinable + uint8_t s_falling:1; //0x04 + uint8_t s_ascending:1; //0x08 + uint8_t s_digging:1; //0x10 + uint8_t s_climbing:1; //0x20 + uint8_t s_climb_ending:1; //0x40 + uint8_t s_building:1; //0x80 + + uint8_t s_blocking:1; //0x01 + uint8_t s_bashing:1; //0x02 + uint8_t s_floating:1; //0x04 + uint8_t s_mining:1; //0x08 + uint8_t s_drawning:1; //0x10 + uint8_t s_ending:1; //0x20 + uint8_t s_dying:1; //0x40 + uint8_t s_exploding2:1; //0x80 +} __attribute__ ((__packed__)); + +union state { + uint16_t raw; + struct _state bits; +}; + +enum state_masks { + s_splatting = 0x01, + s_exploding = 0x02, + s_falling = 0x04, + s_ascending = 0x08, + s_digging = 0x10, + s_climbing = 0x20, + s_climb_ending = 0x40, + s_building = 0x80, + + s_blocking = 0x0100, + s_bashing = 0x0200, + s_floating = 0x0400, + s_mining = 0x0800, + s_drawning = 0x1000, + s_ending = 0x2000, + s_dying = 0x4000, + s_exploding2 = 0x8000 +}; + +struct _flags1 { + uint8_t fl1_cap_climber:1; // 0x01 + uint8_t fl1_unused:6; + uint8_t fl1_walk_pause_for_shruggling:1; // 0x80 +} __attribute__ ((__packed__)); + +union flags1 { + uint8_t raw; + struct _flags1 bits; +}; + +enum flags1_masks { + fl1_cap_climber = 0x01; + fl1_walk_pause_for_shruggling = 0x80; +} + +struct _lemm_data { + /* First lemm is at ds:si == 0b55:0085 */ + uint16_t x_effective; //0x0 - 0x1 + uint16_t y_effective; //0x2 - 0x3 + int16_t x_spr_offset; //0x4 - 0x5 + int16_t y_spr_offset; //0x6 - 0x7 + union state state; //0x8 - 0x9 + uint8_t b_10,b_11; + uint16_t spr_data_ptr; //0xc - 0xd + uint8_t floattime_dble; //0xe + uint8_t b_15,b_16,b_17,b_18,b_19; + uint16_t ptr2; //0x14 - 0x15 + uint8_t b_22,b_23,b_24,b_25,b_26,b_27,b_28,b_29,b_30,b_31; + uint8_t expl_countdown; //0x20 + uint8_t steps_remain; //0x21 + uint8_t b_34; + uint8_t falldist; //0x23 + union flags1 flags1; //0x24 + uint8_t cap_floater; //0x25 + uint8_t is_gone; //0x26 + int8_t direction; //0x27 + uint8_t spr_frame; //0x28 + uint8_t draw_hint; //0x29 + uint8_t b_42,b_43,b_44; +} __attribute__ ((__packed__)); + +union lemm_data { + unsigned char raw[0x2d]; + struct _lemm_data s; +}; + +enum draw_hint { + hint_nothing=0x00, hint_falling=0x04, hint_special1=0x08, /* climbing or slow falling or shruggling */ + hint_walking=0x09, hint_building=0x10, hint_mining=0x18, hint_bashing=0x20 +}; + +struct _avail_skills { + uint8 sk_climber, sk_climber2, sk_climber_tag; // [0x67] + uint8 sk_floater, sk_floater2, sk_floater_tag; // [0x6a] + uint8 sk_bomber, sk_bomber2, sk_bomber_tag; // [0x6d] + uint8 sk_blocker, sk_blocker2, sk_blocker_tag; // [0x70] + uint8 sk_builder, sk_builder2, sk_builder_tag; // [0x73] + uint8 sk_basher, sk_basher2, sk_basher_tag; // [0x76] + uint8 sk_miner, sk_miner2, sk_miner_tag; // [0x79] + uint8 sk_digger, sk_digger2, sk_digger_tag; // [0x7c] +} __attribute__ ((__packed__)); + +struct game_data { + /* ds == 0x0b55 */ + uint8 unk1[0x27]; // TODO + uint8 paused; // [0x28] + uint8 unk2[0x10]; // TODO + uint8 lemm_count_to_process; // [0x39] + uint8 lemm_spawned_count; // [0x40] + uint8 unk3; // TODO + uint8 lemm_out_count; // [0x42] + uint8 unk4; // TODO + uint8 lemm_level_count; // [0x44] + uint8 next_spawn_ticks; // [0x45] + uint8 spawn_rate_ticks; // [0x46] + uint8 unk5[0x20]; // TODO + struct _avail_skills avail_skills; // [0x67] - [0x7e] + uint8 unk6[0x06]; // TODO + struct _lemm_data lemmings[100]; // [0x85] +} __attribute__ ((__packed__)); + +#endif /*_DOS_LEMM_H*/ diff --git a/reverse-engineering/dosbox_snif/int16todec.c b/reverse-engineering/dosbox_snif/int16todec.c new file mode 100644 index 0000000..6499bf6 --- /dev/null +++ b/reverse-engineering/dosbox_snif/int16todec.c @@ -0,0 +1,9 @@ +#include +#include + +int main() { + int16_t i; + scanf("%x", &i); + printf("0x%04x => %i\n", i, i); + return 0; +} diff --git a/reverse-engineering/dosbox_snif/main_dump.c b/reverse-engineering/dosbox_snif/main_dump.c new file mode 100644 index 0000000..68bd4c0 --- /dev/null +++ b/reverse-engineering/dosbox_snif/main_dump.c @@ -0,0 +1,39 @@ +#include "rsp.h" +#include "rsp_lemm.h" +#include "utils.h" + +#include /* memset() */ +#include /* printf() */ + +int main(int argc, char *argv[]) { + int rv, end=0; + struct rsp_state rsp; + char ds_si[10], command[16]; + + rv=rsp_lemm_init(&rsp, ds_si); + if ( rv != 0 ) { + printf("Error rsp_lemm_init() returns %i\n", rv); + return 1; + } + + while (!end) { + rsp_query(&rsp, "c"); // Continue + if ( rsp.replied != 1 ) printf("Bug 03\n"); + rsp_recv_full(&rsp); + if ( rsp_check_and_clear(&rsp, "S05") != 0 ) printf("Bug 04\n"); + + snprintf(command, 15, "m%s,0x2d", ds_si); + rsp_query(&rsp, command); // Read a lemming record + if ( rsp_decode(&rsp) != 0x2d * 2 ) { + printf("Bug 07\n"); + } else { + printf("%s\n", rsp.decoded); + } + } + + + rsp_quit(&rsp); + return 0; +} + + diff --git a/reverse-engineering/dosbox_snif/main_dump_delta.c b/reverse-engineering/dosbox_snif/main_dump_delta.c new file mode 100644 index 0000000..8db3671 --- /dev/null +++ b/reverse-engineering/dosbox_snif/main_dump_delta.c @@ -0,0 +1,182 @@ +#include "rsp.h" +#include "rsp_lemm.h" +#include "utils.h" +#include "dos_lemm.h" + +#include /* uint16_t... */ +#include /* strcpy() */ +#include /* printf() */ + + +int main(int argc, char *argv[]) { + int i, rv, similar_frames, end; + struct rsp_state rsp; + char ds_si[10], command[16]; + union lemm_data lemm, prevlemm; + char draw_hint_str[256][16]; + char state_str[16][16]; + + memset(lemm.raw, 0, sizeof(lemm.raw)); + + for (i=0;i<256;i++) strcpy(draw_hint_str[i], "hint_unknown"); + strcpy(draw_hint_str[hint_nothing], "hint_nothing"); + strcpy(draw_hint_str[hint_falling], "hint_falling"); + strcpy(draw_hint_str[hint_special1],"hint_special1"); + strcpy(draw_hint_str[hint_walking], "hint_walking"); + strcpy(draw_hint_str[hint_building],"hint_building"); + strcpy(draw_hint_str[hint_mining], "hint_mining"); + strcpy(draw_hint_str[hint_bashing], "hint_bashing"); + + strcpy(state_str[s_splatting],"s_splatting"); + strcpy(state_str[s_exploding],"s_exploding"); + strcpy(state_str[s_falling],"s_falling"); + strcpy(state_str[s_ascending],"s_ascending"); + strcpy(state_str[s_digging],"s_digging"); + strcpy(state_str[s_climbing],"s_climbing"); + strcpy(state_str[s_climb_ending],"s_climb_ending"); + strcpy(state_str[s_building],"s_building"); + strcpy(state_str[s_blocking],"s_blocking"); + strcpy(state_str[s_bashing],"s_bashing"); + strcpy(state_str[s_floating],"s_floating"); + strcpy(state_str[s_mining],"s_mining"); + strcpy(state_str[s_drawning],"s_drawning"); + strcpy(state_str[s_ending],"s_ending"); + strcpy(state_str[s_dying],"s_dying"); + strcpy(state_str[s_exploding2],"s_exploding2"); + + rv=rsp_lemm_init(&rsp, ds_si); + if ( rv != 0 ) { + printf("Error rsp_lemm_init() returns %i\n", rv); + return 1; + } + + end=0; + similar_frames=0; + while (!end) { + rsp_query(&rsp, "c"); // Continue + if ( rsp.replied != 1 ) printf("Bug 03\n"); + rsp_recv_full(&rsp); + if ( rsp_check_and_clear(&rsp, "S05") != 0 ) printf("Bug 04\n"); + + snprintf(command, 15, "m%s,0x2d", ds_si); + rsp_query(&rsp, command); // Read a lemming record + if ( rsp_decode(&rsp) != 2*sizeof(lemm.raw) ) { + printf("Bug 07\n"); + continue; + } + + memcpy(prevlemm.raw, lemm.raw, sizeof(lemm.raw)); + + //printf("%s\n", rsp.decoded); + rv = hexascii2bin(rsp.decoded, lemm.raw, sizeof(lemm.raw)); + if ( rv != sizeof(lemm.raw) ) { + printf("Bug 08\n"); + continue; + } + + for (i=0; i 0x02) { + // Skip detailing all 80 changes... Just beginning and ending + continue; + } + } + + // If here, an interessting change has been detected + if ( similar_frames > 0) { + printf("(%i similar frames)\n", similar_frames); + } + similar_frames=-1; + + switch(i) { + + case 0x4: // x_spr_offset + i=0x5; // go to the next case (prevents double printing) + case 0x5: // x_spr_offset + printf("x_spr_offset\t%i -> %i\n",prevlemm.s.x_spr_offset, lemm.s.x_spr_offset); + break; + case 0x6: // y_spr_offset + i=0x7; + case 0x7: // y_spr_offset + printf("y_spr_offset\t%i -> %i\n",prevlemm.s.y_spr_offset, lemm.s.y_spr_offset); + break; + case 0x8: // state + i=0x9; + case 0x9: // state + rv=bit_position(lemm.s.state.raw); + switch (rv) { + case -2: + //FIXME : boucle bit par bit car ya parfois de multiple bits... + printf("state\t\t%04x -> %04x (multiple)\n",prevlemm.s.state.raw, lemm.s.state.raw); + break; + case -1: + printf("state\t\t%04x -> %04x (walking...)\n",prevlemm.s.state.raw, lemm.s.state.raw); + break; + default: + printf("state\t\t%04x -> %04x (%s)\n",prevlemm.s.state.raw, lemm.s.state.raw, state_str[rv]); + break; + } + break; + case 0xc: // spr_data_ptr + i=0xd; + case 0xd: // spr_data_ptr + printf("spr_data_ptr\t%04x -> %04x\n",prevlemm.s.spr_data_ptr, lemm.s.spr_data_ptr); + break; + case 0xe: // floattime_dble ? + printf("floattime_dble\t%02x -> %02x\n",prevlemm.s.floattime_dble, lemm.s.floattime_dble); + break; + case 0x14: // ptr2 ? + i=0x15; + case 0x15: // ptr2 ? + printf("ptr2\t\t%04x -> %04x\n",prevlemm.s.ptr2, lemm.s.ptr2); + break; + case 0x20: //expl_countdown + printf("expl_countdown\t%02x -> %02x\n",prevlemm.s.expl_countdown, lemm.s.expl_countdown); + break; + case 0x21: //steps_remain + printf("steps_remain\t%02x -> %02x\n",prevlemm.s.steps_remain, lemm.s.steps_remain); + break; + case 0x23: //falldist + printf("falldist\t%02x -> %02x\n",prevlemm.s.falldist, lemm.s.falldist); + break; + case 0x24: //flags1 + if ( prevlemm.s.flags1.bf.cap_climber != lemm.s.flags1.bf.cap_climber ) { + printf("cap_climber\t%2i -> %2i\n", prevlemm.s.flags1.bf.cap_climber, lemm.s.flags1.bf.cap_climber); + } else if ( prevlemm.s.flags1.bf.walk_pause_for_shruggling != lemm.s.flags1.bf.walk_pause_for_shruggling ) { + printf("walk_pause_for_shruggling\t%2i -> %2i\n", prevlemm.s.flags1.bf.walk_pause_for_shruggling, lemm.s.flags1.bf.walk_pause_for_shruggling); + } else { + printf("flags1.unknown\t%02x -> %02x\n",prevlemm.s.flags1.raw, lemm.s.flags1.raw); + } + break; + case 0x25: //cap_floater + printf("cap_floater\t%02x -> %02x\n",prevlemm.s.cap_floater, lemm.s.cap_floater); + break; + case 0x26: //is_gone + printf("is_gone\t%02x -> %02x\n",prevlemm.s.is_gone, lemm.s.is_gone); + break; + case 0x27: //direction + printf("direction\t%i -> %i\n",prevlemm.s.direction, lemm.s.direction); + break; + case 0x29: //draw_hint ? + printf("draw_hint\t\t%02x -> %02x (%s)\n",prevlemm.s.draw_hint, lemm.s.draw_hint, draw_hint_str[lemm.s.draw_hint]); + break; + default: + printf("(0x%02x)\t\t%02x -> %02x\n", i, prevlemm.raw[i], lemm.raw[i]); + } + } + similar_frames++; + } + rsp_quit(&rsp); + return 0; +} + diff --git a/reverse-engineering/dosbox_snif/main_dump_ds0.c b/reverse-engineering/dosbox_snif/main_dump_ds0.c new file mode 100644 index 0000000..e54589d --- /dev/null +++ b/reverse-engineering/dosbox_snif/main_dump_ds0.c @@ -0,0 +1,61 @@ +#include "rsp.h" +#include "rsp_lemm.h" +#include "utils.h" + +#include /* memset() */ +#include /* printf() */ + +int main(int argc, char *argv[]) { + int rv, i, end=0; + struct rsp_state rsp; + char ds_si[10], command[16]; + unsigned int addr, ds_offset; + + rv=rsp_lemm_init(&rsp, ds_si); + if ( rv != 0 ) { + printf("Error rsp_lemm_init() returns %i\n", rv); + return 1; + } + + while (!end) { + rsp_query(&rsp, "c"); // Continue + if ( rsp.replied != 1 ) printf("Bug 03\n"); + rsp_recv_full(&rsp); + if ( rsp_check_and_clear(&rsp, "S05") != 0 ) printf("Bug 04\n"); + + // For the beginning of the ds segment + ds_offset=0; + /* For this chunk of code : + 000052A3 83E307 and bx,byte +0x7 bx = 0x5660 + lemm.x_effective % 8; + 000052A6 81C36056 add bx,0x5660 // + 000052AA 8A27 mov ah,[bx] ah = [bx]; + */ + ds_offset = 0x5660; + /* For understanding pixel collision tests at 00005280 + di = lemm.y_effective - 16; + if ( di >= 0 ) di=0; //WTF ??? + di *= (LEVEL_WIDTH/8); + di += 0x6d60 + lemm.x_effective / 8; + */ + ds_offset = 0x6d60; + + ds_offset = 0x3f; + for (i=0;i<8;i++) { + addr = (0xb55 << 4) + ds_offset + (i * 0x20); + snprintf(command, 15, "m%06x,0x20", addr ); + rsp_query(&rsp, command); + if ( rsp_decode(&rsp) != 0x20 *2) { + printf("%06x : Bug\n", addr); + } else { + printf("%06x : %s\n", addr, rsp.decoded); + } + } + printf("\n"); + } + + + rsp_quit(&rsp); + return 0; +} + + diff --git a/reverse-engineering/dosbox_snif/main_poke.c b/reverse-engineering/dosbox_snif/main_poke.c new file mode 100644 index 0000000..e0048fa --- /dev/null +++ b/reverse-engineering/dosbox_snif/main_poke.c @@ -0,0 +1,64 @@ +#include "rsp.h" +#include "rsp_lemm.h" +#include "utils.h" + +#include /* memset() */ +#include /* printf() */ + +int main(int argc, char *argv[]) { + int rv, i, end_input, end_loop; + struct rsp_state rsp; + char ds_si[10], command[16], input[100]; + unsigned int poke_base, poke_off, poke_val; + + rv=rsp_lemm_init(&rsp, ds_si); + if ( rv != 0 ) { + printf("Error rsp_lemm_init() returns %i\n", rv); + return 1; + } + if ( sscanf(ds_si, "%x", &poke_base) != 1 ) printf("Bug 20\n");; + + end_loop=0; + while (!end_loop) { + rsp_query(&rsp, "c"); // Continue + if ( rsp.replied != 1 ) printf("Bug 03\n"); + rsp_recv_full(&rsp); + if ( rsp_check_and_clear(&rsp, "S05") != 0 ) printf("Bug 04\n"); + + snprintf(command, 15, "m%s,0x2d", ds_si); + rsp_query(&rsp, command); // Read a lemming record + if ( rsp_decode(&rsp) != 0x2d * 2 ) { + printf("Bug 07\n"); + } else { + for (i=0; rsp.decoded[i]!='\0'; i++) { + putchar(rsp.decoded[i]); + if (i%2==1) putchar(' '); + if (i%16==15) putchar(' '); + } + putchar('\n'); + } + + end_input=0; + do { + printf("address value ? "); fflush(stdout); + if ( fgets(input, 99, stdin) == NULL ) { + //printf("pb fgets\n"); + end_input=1; continue; + } + if ( sscanf(input,"%x %x", &poke_off, &poke_val) != 2 ) { + //printf("pb sscanf\n"); + end_input=1; continue; + } + if ( rsp_poke(&rsp, poke_base + poke_off, poke_val) != 0 ) { + printf("Bug 21\n"); + end_input=1; continue; + } + } while ( !end_input ); + } + + + rsp_quit(&rsp); + return 0; +} + + diff --git a/reverse-engineering/dosbox_snif/main_validate_code.c b/reverse-engineering/dosbox_snif/main_validate_code.c new file mode 100644 index 0000000..a016a54 --- /dev/null +++ b/reverse-engineering/dosbox_snif/main_validate_code.c @@ -0,0 +1,12 @@ +#include "dos_lemm.h" + +int main() { + struct game_data g; + struct _lemm_data *lemm; + + lemm = g.lemmings; + lemm->draw_hint = hint_walking; + + return lemm->draw_hint; +} + diff --git a/reverse-engineering/dosbox_snif/rsp.c b/reverse-engineering/dosbox_snif/rsp.c new file mode 100644 index 0000000..c9957b7 --- /dev/null +++ b/reverse-engineering/dosbox_snif/rsp.c @@ -0,0 +1,243 @@ +#include "rsp.h" + +/* recv() */ +#include +#include + +#include /* memset(), strncmp() */ +#include /* perror(), fprintf(), snprintf(), sscanf() */ +#include /* malloc(), free() */ +#include /* close() */ +#include /* EAGAIN... */ + +void _rsp_sniff_garbage(struct rsp_state *rsp) { + int recvbytes, rv; + + // Sniff garbages before sending command + recvbytes = recv(rsp->sockfd, rsp->response, rsp->data_maxlen, MSG_DONTWAIT); + if ( recvbytes < 0 ) { + rv = errno; + if ( rv == EAGAIN || rv == EWOULDBLOCK ) { + /* No garbage found, that's a good news */ + } else { + LOG_DEBUG("! <-(error %i)\n", rv); + } + recvbytes=0; + } + rsp->response[recvbytes] = '\0'; + if ( recvbytes > 0 ) { + LOG_DEBUG("! <-'%s'\n",rsp->response); + } +} + +int rsp_recv_full(struct rsp_state *rsp) { + + int rv, error=0, complete=0, full=0, sentbytes; + ssize_t bufoldpos=0, bufpos=0; + char *bom=NULL, *eom=NULL, *ptr; + unsigned char c, cack='+'; + unsigned int computed_checksum, read_checksum; + + do { + rv = recv(rsp->sockfd, rsp->response + bufpos, rsp->data_maxlen - bufpos, 0); + if ( rv < 0 ) { + switch (errno) { + case EAGAIN: + continue; + default: + error=1; + continue; + } + } + if ( rv == 0 ) { + error=1; + continue; + } + + bufoldpos = bufpos; + bufpos += rv; + + if ( bom == NULL ) { + bom = memchr(rsp->response + bufoldpos, '$', bufpos - bufoldpos); + } + + if ( bom != NULL && eom == NULL ) { + eom = memchr(bom, '#', bufpos - (bom - rsp->response) ); + } + + complete = bom && eom && (eom+2) <= (rsp->response + bufpos); // 2 char checksum after EOM + full = (bufpos >= rsp->data_maxlen); + + } while (!error && !complete && !full); + + if (error) return 1; + if (full) return 2; + + rsp->response[bufpos]='\0'; + + c=eom[3]; + eom[3]='\0'; + LOG_DEBUG(" <- '%s'\n", rsp->response); + + if ( (eom+3) < (rsp->response + bufpos - 1)) { + eom[3]=c; + LOG_DEBUG("? <- '%s'\n", eom+3); + } + + + rsp->response_len = eom - bom - 1; + rsp->response_bom = bom; + rsp->response_eom = eom; + + computed_checksum=0; + for (ptr = bom+1; ptr < eom; ptr++) { + computed_checksum = (computed_checksum + ((unsigned char)*ptr) ) % 256; + } + + rv = sscanf(eom + 1, "%02x", &read_checksum); + if ( rv != 1 || computed_checksum != read_checksum) return 3; + + rsp->replied = 1; + + if (rsp->noackmode !=1) { + sentbytes = send(rsp->sockfd, &cack, 1, 0); + if ( sentbytes < 1 ) return 4; + LOG_DEBUG("-> '+'\n"); + } + + return 0; +} + +int rsp_init(int sockfd, int data_maxlen, struct rsp_state *rsp) { + memset(rsp,0,sizeof(struct rsp_state)); + rsp->sockfd = sockfd; + rsp->data_maxlen = data_maxlen; + + rsp->command = malloc(data_maxlen+1); + if ( rsp->command == NULL ) return 1; + + rsp->response = malloc(data_maxlen+1); + if ( rsp->response == NULL ) return 1; + + rsp->decoded = malloc(data_maxlen+1); + if ( rsp->decoded == NULL ) return 1; + +/* + rsp_query(rsp, "QStartNoAckMode"); + if ( rsp_check_and_clear(rsp, "OK") == 0 ) rsp->noackmode=1; +*/ + return 0; +} + +void rsp_quit(struct rsp_state *rsp) { + //rsp_query(rsp, "k"); + if ( rsp->command != NULL ) free(rsp->command); + if ( rsp->response != NULL ) free(rsp->response); + if ( rsp->decoded != NULL ) free(rsp->decoded); + close(rsp->sockfd); + memset(rsp,0,sizeof(struct rsp_state)); +} + +void rsp_send_break(struct rsp_state *rsp) { + int sentbytes; + char cbreak=3; + + rsp->replied = 0; + rsp->response_len = 0; + + _rsp_sniff_garbage(rsp); + + sentbytes = send(rsp->sockfd, &cbreak, 1, 0); + if ( sentbytes < 1 ) return; + LOG_DEBUG("-> '^C'\n"); + + rsp_recv_full(rsp); +} + +void rsp_query(struct rsp_state *rsp, char command[]) { + int sentbytes; + unsigned int checksum, i; + unsigned char c; + + + rsp->replied = 0; + rsp->response_len = 0; + + i=0; checksum=0; + while ( (c=command[i++]) != '\0' ) { + checksum = (checksum + c ) % 256; + } + + rsp->command_len = snprintf(rsp->command, rsp->data_maxlen, "$%s#%02x", command, checksum); + if (rsp->command_len < 5) return; + + _rsp_sniff_garbage(rsp); + + sentbytes = send(rsp->sockfd, rsp->command, rsp->command_len, 0); + if ( sentbytes < rsp->command_len ) return; + LOG_DEBUG("-> '%s'\n", rsp->command); + + + rsp_recv_full(rsp); +} + +int rsp_check_and_clear(struct rsp_state *rsp, char expected_response[]) { + + int expected_responselen = strlen(expected_response); + + if ( rsp->replied != 1 ) return 1; + rsp->replied = 0; + + if ( rsp->response_len < expected_responselen ) return 2; + if ( strncmp(rsp->response_bom + 1, expected_response, expected_responselen) != 0 ) return 3; + + return 0; +} + +int rsp_decode(struct rsp_state *rsp) { +/* +Response data can be run-length encoded to save space. Run-length encoding replaces runs of identical characters with one instance of the repeated character, followed by a ‘*’ and a repeat count. The repeat count is itself sent encoded, to avoid binary characters in data: a value of n is sent as n+29. For a repeat count greater or equal to 3, this produces a printable ascii character, e.g. a space (ascii code 32) for a repeat count of 3. (This is because run-length encoding starts to win for counts 3 or more.) Thus, for example, ‘0* ’ is a run-length encoding of “0000”: the space character after ‘*’ means repeat the leading 0 32 - 29 = 3 more times. + +The printable characters ‘#’ and ‘$’ or with a numeric value greater than 126 must not be used. Runs of six repeats (‘#’) or seven repeats (‘$’) can be expanded using a repeat count of only five (‘"’). For example, ‘00000000’ can be encoded as ‘0*"00’. +*/ + char src, *srcptr, *dstptr; + int repe, max; + + if ( rsp->replied != 1 ) return -1; + + dstptr = rsp->decoded; + for ( srcptr = rsp->response_bom+1; srcptr < rsp->response_eom; srcptr++ ) { + // FIXME : implemnt RLE decoding + src = *srcptr; + switch (src) { + case '*': + srcptr++; + repe=(*srcptr)-29; + if (repe < 2 ) return -1; + max = rsp->decoded + rsp->data_maxlen - 1 - dstptr; + if ( repe > max ) { repe = max; } + memset(dstptr, *(srcptr-2), repe); + dstptr += repe; + break; + default: + *(dstptr++) = *srcptr; + break; + } + } + *dstptr='\0'; + + return dstptr - rsp->decoded; +} + +int rsp_poke(struct rsp_state *rsp, unsigned int poke_addr, unsigned int poke_value) { + char command[16]; + printf("DEBUG : rsp_poke()\n"); + if ( snprintf(command, 15, "M %4x,2:%2x", poke_addr & 0xffff, poke_value & 0xff) < 11 ) return 1; + printf("DEBUG : command == '%s'\n", command); + rsp_query(rsp, command); // Send the poke command to GDB stub + printf("DEBUG : response == '%s'\n", rsp->response); + if ( rsp_check_and_clear(rsp, "OK") != 0 ) return 2; + + return 0; +} + diff --git a/reverse-engineering/dosbox_snif/rsp.h b/reverse-engineering/dosbox_snif/rsp.h new file mode 100644 index 0000000..c8f1378 --- /dev/null +++ b/reverse-engineering/dosbox_snif/rsp.h @@ -0,0 +1,27 @@ +#ifndef _RSP_H +#define _RSP_H + +#define LOG_DEBUG(...) +//#include +//#define LOG_DEBUG(...) printf(__VA_ARGS__) + +struct rsp_state { + int sockfd; + int data_maxlen; + int noackmode; + int replied; + int command_len, response_len; + char *command, *response, *decoded; /* Malloc'ed */ + char *response_bom, *response_eom; /* Just pointers on *response string */ +}; + +int rsp_init(int sockfd, int data_maxlen, struct rsp_state *rsp); +void rsp_quit(struct rsp_state *rsp); +void rsp_send_break(struct rsp_state *rsp); +void rsp_query(struct rsp_state *rsp, char command[]); +int rsp_check_and_clear(struct rsp_state *rsp, char expected_response[]); +int rsp_recv_full(struct rsp_state *rsp); +int rsp_decode(struct rsp_state *rsp); +int rsp_poke(struct rsp_state *rsp, unsigned int poke_addr, unsigned int poke_value); + +#endif /*_RSP_H*/ diff --git a/reverse-engineering/dosbox_snif/rsp_lemm.c b/reverse-engineering/dosbox_snif/rsp_lemm.c new file mode 100644 index 0000000..e39ef30 --- /dev/null +++ b/reverse-engineering/dosbox_snif/rsp_lemm.c @@ -0,0 +1,65 @@ +#include "rsp_lemm.h" +#include "utils.h" + +#include /* memset(), strncmp() */ +#include /* printf() */ + +int rsp_lemm_init(struct rsp_state *rsp, char *ds_si) { + int rv; + int sockfd; + + memset(ds_si,'X',10); + ds_si[9]='\0'; + + rv = tcp_client_init(HOST, PORT, &sockfd); + if ( rv != 0 ) return rv; + + rsp_init(sockfd, MAXDATASIZE-1, rsp); + +/* + rsp_query(rsp, "qRcmd,666c61745f6569702c30"); //flat_eip,0 + if ( rsp_check_and_clear(rsp, "OK") != 0 ) printf("Bug\n"); +*/ + rsp_query(rsp, "?"); + if ( rsp_check_and_clear(rsp, "S05") != 0 ) { + // The program is not stopped + rsp_send_break(rsp); // Request to freeze the program + if ( rsp->replied != 1 ) return 10; + } + + rsp_query(rsp, "Z0,38C4,1"); // Set execution breakpoint at 0208:1844 (0x38C4) + if ( rsp_check_and_clear(rsp, "OK") != 0 ) return 11; + + do { + rsp_query(rsp, "c"); // Continue + if ( rsp->replied != 1 ) continue; //return 12; + rsp_recv_full(rsp); + if ( rsp_check_and_clear(rsp, "S05") != 0 ) continue; //return 13; +// (void) rsp_check_and_clear(rsp, "S05"); + + rsp_query(rsp, "p8"); // Read $eip (/!\ byte order. ex : $e4b0* !#76 ) +// if ( rsp_check_and_clear(rsp, "c4380000") != 0 ) return 14; + } while ( rsp_check_and_clear(rsp, "c4380000") != 0 ); + + rsp_query(rsp, "pc"); // Read $ds + if ( rsp_decode(rsp) <8 ) return 15; + ds_si[0]=rsp->decoded[2]; + ds_si[1]=rsp->decoded[3]; + ds_si[2]=rsp->decoded[0]; + ds_si[3]=rsp->decoded[1]; + ds_si[4]=':'; + + rsp_query(rsp, "p6"); // Read $si + if ( rsp_decode(rsp) <8 ) return 16; + ds_si[5]=rsp->decoded[2]; + ds_si[6]=rsp->decoded[3]; + ds_si[7]=rsp->decoded[0]; + ds_si[8]=rsp->decoded[1]; + + printf("ds:si == %s\n", ds_si); + flatten(ds_si); + printf("$ds_si == %s\n", ds_si); + + return 0; +} + diff --git a/reverse-engineering/dosbox_snif/rsp_lemm.h b/reverse-engineering/dosbox_snif/rsp_lemm.h new file mode 100644 index 0000000..bd95d4f --- /dev/null +++ b/reverse-engineering/dosbox_snif/rsp_lemm.h @@ -0,0 +1,13 @@ +#ifndef _RSP_LEMM_H +#define _RSP_LEMM_H + +#include "rsp.h" + +#define HOST "localhost" +#define PORT "1234" +#define MAXDATASIZE 1400 + + +int rsp_lemm_init(struct rsp_state *rsp, char *ds_si); + +#endif /*_RSP_LEMM_H*/ diff --git a/reverse-engineering/dosbox_snif/utils.c b/reverse-engineering/dosbox_snif/utils.c new file mode 100644 index 0000000..8e26d46 --- /dev/null +++ b/reverse-engineering/dosbox_snif/utils.c @@ -0,0 +1,112 @@ +#include "utils.h" + +/* socket() */ +#include +#include +#include +/* getaddrinfo() */ +#include +#include +/* inet_ntop() */ +#include +#define GET_SOCK_IN_ADDR(sa) (((struct sockaddr*)sa)->sa_family == AF_INET)?(void *)&(((struct sockaddr_in*)sa)->sin_addr):(void *)&(((struct sockaddr_in6*)sa)->sin6_addr) + +#include /* memset(), strncmp() */ +#include /* perror(), fprintf(), snprintf(), sscanf() */ +#include /* malloc(), free() */ +#include /* close() */ +#include /* EAGAIN... */ + + +int tcp_client_init(char host[], char port[], int *sockfd) { + int rv, flag=1; + char s[INET6_ADDRSTRLEN]; + struct addrinfo hints, *servinfo, *p; + memset(&hints,0,sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + if ((rv = getaddrinfo(host, port, &hints, &servinfo)) != 0) { + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); + return 1; + } + + + // loop through all the results and connect to the first we can + for(p = servinfo; p != NULL; p = p->ai_next) { + if ((*sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) { + //perror("client: socket"); + continue; + } + + if ( setsockopt(*sockfd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(flag)) != 0 ) { + perror("client: setsockopt TCP_NODELAY"); + } + + if (connect(*sockfd, p->ai_addr, p->ai_addrlen) == -1) { + close(*sockfd); + //perror("client: connect"); + continue; + } + + break; + } + + freeaddrinfo(servinfo); + + if (p == NULL) { + fprintf(stderr, "client: failed to connect\n"); + return 2; + } + + inet_ntop(p->ai_family, GET_SOCK_IN_ADDR(p->ai_addr), s, sizeof s); + printf("client: connecting to %s\n", s); + + return 0; +} + +void flatten(char *seg_off) { + unsigned int seg=0, off=0, flat; + sscanf(seg_off, "%4x", &seg); + sscanf(seg_off+5, "%4x", &off); + flat= (seg<<4) + off; + snprintf(seg_off, 9, "%x", flat); +} + + +int hexascii2bin(char src[], void *dst, int maxlen) { + int i; + unsigned char offset; + for (i=0; i= '0' && src[i] <= '9' ) offset='0'; + else if ( src[i] >= 'a' && src[i] <= 'f' ) offset='a' - 10; + else if ( src[i] >= 'A' && src[i] <= 'F' ) offset='A' - 10; + else break; + + if ( i % 2 == 0 ) { + ((unsigned char *)dst)[i/2] = (src[i]-offset) << 4; + } else { + ((unsigned char *)dst)[i/2] += (src[i]-offset); + } + } + return i/2; +} + +// Indicate the position of the bit that is on +// If multiple bits activated, returns -2 +// If no bits activated, return -1 +int bit_position(uint16_t flags) { + int i, pos; + pos=-1; // Not found yet + for (i=0;i<16;i++) { + if ( (flags >> i) & 0x0001 ) { + if ( pos == -1 ) { + pos=i; + } else { + return -2; + } + } + } + return pos; +} diff --git a/reverse-engineering/dosbox_snif/utils.h b/reverse-engineering/dosbox_snif/utils.h new file mode 100644 index 0000000..a7031a8 --- /dev/null +++ b/reverse-engineering/dosbox_snif/utils.h @@ -0,0 +1,11 @@ +#ifndef _UTILS_H +#define _UTILS_H + +#include + +int tcp_client_init(char host[], char port[], int *sockfd); +void flatten(char *seg_off); +int hexascii2bin(char src[], void *dst, int maxlen); +int bit_position(uint16_t flags); + +#endif /*_UTIL_H*/ diff --git a/reverse-engineering/work/seg_code_0208.txt b/reverse-engineering/work/seg_code_0208.txt index 0efbed8..21a4ca0 100644 --- a/reverse-engineering/work/seg_code_0208.txt +++ b/reverse-engineering/work/seg_code_0208.txt @@ -1736,7 +1736,7 @@ main_loop_ingame: 00000F49 3C30 cmp al,0x30 if ( al == 0x30 ) goto no_lemm_left; 00000F4B 7502 jnz 0xf4f // 00000F4D EB57 jmp short 0xfa6 // -00000F4F 803E2800FF cmp byte [0x28],0xff if ( ! [0x28] ) { +00000F4F 803E2800FF cmp byte [0x28],0xff if ( ! paused ) { 00000F54 7437 jz 0xf8d // 00000F56 FE0E8200 dec byte [0x82] [0x82]--; 00000F5A 7531 jnz 0xf8d if ( [0x82] == 0 ) { @@ -2769,7 +2769,7 @@ no_lemm_left: 0000182E C3 ret void move_lemmings() { -0000182F 803E2800FF cmp byte [0x28],0xff if ([0x28] == 0xff) { # +0000182F 803E2800FF cmp byte [0x28],0xff if ( paused ) { 00001834 7503 jnz 0x1839 00001836 E9DC00 jmp word 0x1915 [0x4d] = 0; # return; @@ -2800,7 +2800,7 @@ no_lemm_left: 0000186F 7403 jz 0x1874 // 00001871 E9350E jmp word 0x26a9 // 00001874 8B4408 mov ax,[si+0x8] // -00001877 23C0 and ax,ax if ( lemm->state.word == 0x0 ) +00001877 23C0 and ax,ax if ( lemm->state.raw == 0x0 ) 00001879 7503 jnz 0x187e goto lbl_walking; 0000187B E9DF00 jmp word 0x195d // 0000187E A90200 test ax,0x2 if ( lemm->state.bits.s_exploding ) @@ -2882,7 +2882,7 @@ label1: 0000193A 7506 jnz 0x1942 // 0000193C FE064900 inc byte [0x49] // 00001940 EBD9 jmp short 0x191b // -00001942 F744080380 test word [si+0x8],0x8003 if ( lemm->state.word & (s_exploding2 | s_splatting | s_exploding) == 0 ) { +00001942 F744080380 test word [si+0x8],0x8003 if ( lemm->state.raw & (s_exploding2 | s_splatting | s_exploding) == 0 ) { 00001947 7504 jnz 0x194d lemm.expl_countdown = 79; 00001949 C644204F mov byte [si+0x20],0x4f } 0000194D FE064900 inc byte [0x49] [0x49]++; @@ -4087,7 +4087,7 @@ lbl_anim_but_no_move: 000026B3 7403 jz 0x26b8 if ( lemm->spr_frame != 7 ) { 000026B5 E949F2 jmp word 0x1901 goto next_lemming; } -000026B8 C744080000 mov word [si+0x8],0x0 lemm->state.word = s_walking; +000026B8 C744080000 mov word [si+0x8],0x0 lemm->state.raw = s_walking; 000026BD C7440A0000 mov word [si+0xa],0x0 //??? 000026C2 C7440C0000 mov word [si+0xc],0x0 lemm->spr_data_ptr = 0; 000026C7 C744105A00 mov word [si+0x10],0x5a //??? @@ -4108,7 +4108,7 @@ lbl_anim_but_no_move: 000026F8 B001 mov al,0x1 000026FA FE4C20 dec byte [si+0x20] lemm.expl_countdown--; 000026FD 7555 jnz 0x2754 if ( lemm.expl_countdown == 0 ) { -000026FF F744080454 test word [si+0x8],0x5404 if ( lemm->state.word == 0x5404 ) { //WTF?? # +000026FF F744080454 test word [si+0x8],0x5404 if ( lemm->state.raw == 0x5404 ) { //WTF?? # 00002704 7551 jnz 0x2757 // 00002706 814C080080 or word [si+0x8],0x8000 lemm->state.bits.s_exploding2 = 1; 0000270B C7440A0800 mov word [si+0xa],0x8 // ??? # @@ -4333,7 +4333,7 @@ lbl_on_exit: 00002997 CD61 int 0x61 00002999 C3 ret void spawn_lemming() { -0000299A 803E2800FF cmp byte [0x28],0xff if ( ![0x28] || ![0x52] ) return; # +0000299A 803E2800FF cmp byte [0x28],0xff if ( paused || ![0x52] ) return; # 0000299F 7503 jnz 0x29a4 // 000029A1 E99F00 jmp word 0x2a43 // 000029A4 803E5200FF cmp byte [0x52],0xff // @@ -4390,7 +4390,7 @@ lbl_on_exit: 00002A43 C3 ret return; } void apply_skill() { -00002A44 803E2800FF cmp byte [0x28],0xff if ( [0x28] || [0x4d] || ![0x60] ) return; +00002A44 803E2800FF cmp byte [0x28],0xff if ( paused || [0x4d] || ![0x60] ) return; 00002A49 7463 jz 0x2aae // 00002A4B 803E4D00FF cmp byte [0x4d],0xff // 00002A50 7502 jnz 0x2a54 // @@ -4441,7 +4441,7 @@ lbl_apply_exploder: 00002ABA 7441 jz 0x2afd // 00002ABC 807C2000 cmp byte [si+0x20],0x0 // 00002AC0 753B jnz 0x2afd // -00002AC2 F7440803C0 test word [si+0x8],0xc003 if ( lemm->state.word & (s_exploding2 | s_dying | s_exploding | s_splatting) !=0 ) +00002AC2 F7440803C0 test word [si+0x8],0xc003 if ( lemm->state.raw & (s_exploding2 | s_dying | s_exploding | s_splatting) !=0 ) 00002AC7 7534 jnz 0x2afd return; 00002AC9 FE0E6D00 dec byte [0x6d] sk_bomber--; 00002ACD C6066F0000 mov byte [0x6f],0x0 sk_bomber_tag=0; @@ -5679,7 +5679,7 @@ try_other_candidate_for_mining: 000037EC 3C0C cmp al,0xc 000037EE 7503 jnz 0x37f3 000037F0 E99B00 jmp word 0x388e -000037F3 803E2800FF cmp byte [0x28],0xff +000037F3 803E2800FF cmp byte [0x28],0xff if ( ! paused ) 000037F8 7503 jnz 0x37fd 000037FA E98C00 jmp word 0x3889 000037FD 803E810000 cmp byte [0x81],0x0 @@ -5734,7 +5734,7 @@ try_other_candidate_for_mining: 00003888 C3 ret 00003889 C6065F00FF mov byte [0x5f],0xff 0000388E C3 ret -0000388F 803E2800FF cmp byte [0x28],0xff +0000388F 803E2800FF cmp byte [0x28],0xff if ( paused ) 00003894 74F8 jz 0x388e 00003896 C606CC1F00 mov byte [0x1fcc],0x0 0000389B A0CF1F mov al,[0x1fcf] @@ -5753,10 +5753,10 @@ try_other_candidate_for_mining: 000038C1 80FB02 cmp bl,0x2 000038C4 7302 jnc 0x38c8 000038C6 EBC6 jmp short 0x388e -000038C8 80362800FF xor byte [0x28],0xff +000038C8 80362800FF xor byte [0x28],0xff paused = !paused; 000038CD A25000 mov [0x50],al 000038D0 EBBC jmp short 0x388e -000038D2 803E2800FF cmp byte [0x28],0xff +000038D2 803E2800FF cmp byte [0x28],0xff if ( paused ) 000038D7 74B5 jz 0x388e 000038D9 22C0 and al,al 000038DB 742B jz 0x3908 @@ -12418,8 +12418,8 @@ try_other_candidate_for_mining: 000070B3 C3 ret } void unk_03() { -000070B4 803E2800FF cmp byte [0x28],0xff -000070B9 745A jz 0x7115 +000070B4 803E2800FF cmp byte [0x28],0xff if ( paused ) return; +000070B9 745A jz 0x7115 // 000070BB BEC817 mov si,0x17c8 000070BE BFE80F mov di,0xfe8 000070C1 B92000 mov cx,0x20 diff --git a/src/dosbox_snif/dos_lemm.h b/src/dosbox_snif/dos_lemm.h deleted file mode 100644 index 4766011..0000000 --- a/src/dosbox_snif/dos_lemm.h +++ /dev/null @@ -1,108 +0,0 @@ -#ifndef _DOS_LEMM_H -#define _DOS_LEMM_H - -uint8 lemm_count_to_process; // [0x39] -uint8 lemm_spawned_count; // [0x40] - -uint8 lemm_out_count; // [0x42] - -uint8 lemm_level_count; // [0x44] -uint8 next_spawn_ticks; // [0x45] -uint8 spawn_rate_ticks; // [0x46] - - -struct _avail_skils { - /* ds:si == 0b5b:0067 */ - uint8 sk_climber, sk_climber2, sk_climber_tag; // [0x67] - uint8 sk_floater, sk_floater2, sk_floater_tag; // [0x6a] - uint8 sk_bomber, sk_bomber2, sk_bomber_tag; // [0x6d] - uint8 sk_blocker, sk_blocker2, sk_blocker_tag; // [0x70] - uint8 sk_builder, sk_builder2, sk_builder_tag; // [0x73] - uint8 sk_basher, sk_basher2, sk_basher_tag; // [0x76] - uint8 sk_miner, sk_miner2, sk_miner_tag; // [0x79] - uint8 sk_digger, sk_digger2, sk_digger_tag; // [0x7c] -}; - -struct _state { - uint8_t s_splatting:1; //0x01 - uint8_t s_exploding:1; //0x02 combinable - uint8_t s_falling:1; //0x04 - uint8_t s_ascending:1; //0x08 - uint8_t s_digging:1; //0x10 - uint8_t s_climbing:1; //0x20 - uint8_t s_climb_ending:1; //0X40 - uint8_t s_building:1; //0X80 - - uint8_t s_blocking:1; //0x01 - uint8_t s_bashing:1; //0x02 - uint8_t s_floating:1; //0x04 - uint8_t s_mining:1; //0x08 - uint8_t s_drawning:1; //0x10 - uint8_t s_ending:1; //0x20 - uint8_t s_dying:1; //0X40 - uint8_t s_exploding2:1; //0X80 -} __attribute__ ((__packed__)); - -union state { - uint16_t raw; - struct _state bf; -}; - -struct _flags1 { - uint8_t cap_climber:1; // 0x1 - uint8_t unused_bit_1:1; - uint8_t unused_bit_2:1; - uint8_t unused_bit_3:1; - uint8_t unused_bit_4:1; - uint8_t unused_bit_5:1; - uint8_t unused_bit_6:1; - uint8_t walk_pause_for_shruggling:1; // 0X80 -} __attribute__ ((__packed__)); - -union flags1 { - uint8_t raw; - struct _flags1 bf; -}; - -struct _lemm_data { - /* First lemm is at ds:si == 0b55:0085 */ - uint16_t x_effective; //0x0 - 0x1 - uint16_t y_effective; //0x2 - 0x3 - int16_t x_spr_offset; //0x4 - 0x5 - int16_t y_spr_offset; //0x6 - 0x7 - union state state; //0x8 - 0x9 - uint8_t b_10,b_11; - uint16_t spr_data_ptr; //0xc - 0xd - uint8_t floattime_dble; //0xe - uint8_t b_15,b_16,b_17,b_18,b_19; - uint16_t ptr2; //0x14 - 0x15 - uint8_t b_22,b_23,b_24,b_25,b_26,b_27,b_28,b_29,b_30,b_31; - uint8_t expl_countdown; //0x20 - uint8_t steps_remain; //0x21 - uint8_t b_34; - uint8_t falldist; //0x23 - union flags1 flags1; //0x24 - uint8_t cap_floater; //0x25 - uint8_t is_gone; //0x26 - int8_t direction; //0x27 - uint8_t spr_frame; //0x28 - uint8_t draw_hint; //0x29 - uint8_t b_42,b_43,b_44; -} __attribute__ ((__packed__)); - -union lemm_data { - unsigned char raw[0x2d]; - struct _lemm_data s; -}; - -enum draw_hint { - hint_nothing=0x00, hint_falling=0x04, hint_special1=0x08, /* climbing or slow falling or shruggling */ - hint_walking=0x09, hint_building=0x10, hint_mining=0x18, hint_bashing=0x20 -}; - -enum state_bit { - s_splatting=0, s_exploding, s_falling, s_ascending, s_digging, s_climbing, s_climb_ending, s_building, - s_blocking, s_bashing, s_floating, s_mining, s_drawning, s_ending, s_dying, s_exploding2 -}; - -#endif /*_DOS_LEMM_H*/ diff --git a/src/dosbox_snif/int16todec.c b/src/dosbox_snif/int16todec.c deleted file mode 100644 index 6499bf6..0000000 --- a/src/dosbox_snif/int16todec.c +++ /dev/null @@ -1,9 +0,0 @@ -#include -#include - -int main() { - int16_t i; - scanf("%x", &i); - printf("0x%04x => %i\n", i, i); - return 0; -} diff --git a/src/dosbox_snif/main_dump.c b/src/dosbox_snif/main_dump.c deleted file mode 100644 index 68bd4c0..0000000 --- a/src/dosbox_snif/main_dump.c +++ /dev/null @@ -1,39 +0,0 @@ -#include "rsp.h" -#include "rsp_lemm.h" -#include "utils.h" - -#include /* memset() */ -#include /* printf() */ - -int main(int argc, char *argv[]) { - int rv, end=0; - struct rsp_state rsp; - char ds_si[10], command[16]; - - rv=rsp_lemm_init(&rsp, ds_si); - if ( rv != 0 ) { - printf("Error rsp_lemm_init() returns %i\n", rv); - return 1; - } - - while (!end) { - rsp_query(&rsp, "c"); // Continue - if ( rsp.replied != 1 ) printf("Bug 03\n"); - rsp_recv_full(&rsp); - if ( rsp_check_and_clear(&rsp, "S05") != 0 ) printf("Bug 04\n"); - - snprintf(command, 15, "m%s,0x2d", ds_si); - rsp_query(&rsp, command); // Read a lemming record - if ( rsp_decode(&rsp) != 0x2d * 2 ) { - printf("Bug 07\n"); - } else { - printf("%s\n", rsp.decoded); - } - } - - - rsp_quit(&rsp); - return 0; -} - - diff --git a/src/dosbox_snif/main_dump_delta.c b/src/dosbox_snif/main_dump_delta.c deleted file mode 100644 index 8db3671..0000000 --- a/src/dosbox_snif/main_dump_delta.c +++ /dev/null @@ -1,182 +0,0 @@ -#include "rsp.h" -#include "rsp_lemm.h" -#include "utils.h" -#include "dos_lemm.h" - -#include /* uint16_t... */ -#include /* strcpy() */ -#include /* printf() */ - - -int main(int argc, char *argv[]) { - int i, rv, similar_frames, end; - struct rsp_state rsp; - char ds_si[10], command[16]; - union lemm_data lemm, prevlemm; - char draw_hint_str[256][16]; - char state_str[16][16]; - - memset(lemm.raw, 0, sizeof(lemm.raw)); - - for (i=0;i<256;i++) strcpy(draw_hint_str[i], "hint_unknown"); - strcpy(draw_hint_str[hint_nothing], "hint_nothing"); - strcpy(draw_hint_str[hint_falling], "hint_falling"); - strcpy(draw_hint_str[hint_special1],"hint_special1"); - strcpy(draw_hint_str[hint_walking], "hint_walking"); - strcpy(draw_hint_str[hint_building],"hint_building"); - strcpy(draw_hint_str[hint_mining], "hint_mining"); - strcpy(draw_hint_str[hint_bashing], "hint_bashing"); - - strcpy(state_str[s_splatting],"s_splatting"); - strcpy(state_str[s_exploding],"s_exploding"); - strcpy(state_str[s_falling],"s_falling"); - strcpy(state_str[s_ascending],"s_ascending"); - strcpy(state_str[s_digging],"s_digging"); - strcpy(state_str[s_climbing],"s_climbing"); - strcpy(state_str[s_climb_ending],"s_climb_ending"); - strcpy(state_str[s_building],"s_building"); - strcpy(state_str[s_blocking],"s_blocking"); - strcpy(state_str[s_bashing],"s_bashing"); - strcpy(state_str[s_floating],"s_floating"); - strcpy(state_str[s_mining],"s_mining"); - strcpy(state_str[s_drawning],"s_drawning"); - strcpy(state_str[s_ending],"s_ending"); - strcpy(state_str[s_dying],"s_dying"); - strcpy(state_str[s_exploding2],"s_exploding2"); - - rv=rsp_lemm_init(&rsp, ds_si); - if ( rv != 0 ) { - printf("Error rsp_lemm_init() returns %i\n", rv); - return 1; - } - - end=0; - similar_frames=0; - while (!end) { - rsp_query(&rsp, "c"); // Continue - if ( rsp.replied != 1 ) printf("Bug 03\n"); - rsp_recv_full(&rsp); - if ( rsp_check_and_clear(&rsp, "S05") != 0 ) printf("Bug 04\n"); - - snprintf(command, 15, "m%s,0x2d", ds_si); - rsp_query(&rsp, command); // Read a lemming record - if ( rsp_decode(&rsp) != 2*sizeof(lemm.raw) ) { - printf("Bug 07\n"); - continue; - } - - memcpy(prevlemm.raw, lemm.raw, sizeof(lemm.raw)); - - //printf("%s\n", rsp.decoded); - rv = hexascii2bin(rsp.decoded, lemm.raw, sizeof(lemm.raw)); - if ( rv != sizeof(lemm.raw) ) { - printf("Bug 08\n"); - continue; - } - - for (i=0; i 0x02) { - // Skip detailing all 80 changes... Just beginning and ending - continue; - } - } - - // If here, an interessting change has been detected - if ( similar_frames > 0) { - printf("(%i similar frames)\n", similar_frames); - } - similar_frames=-1; - - switch(i) { - - case 0x4: // x_spr_offset - i=0x5; // go to the next case (prevents double printing) - case 0x5: // x_spr_offset - printf("x_spr_offset\t%i -> %i\n",prevlemm.s.x_spr_offset, lemm.s.x_spr_offset); - break; - case 0x6: // y_spr_offset - i=0x7; - case 0x7: // y_spr_offset - printf("y_spr_offset\t%i -> %i\n",prevlemm.s.y_spr_offset, lemm.s.y_spr_offset); - break; - case 0x8: // state - i=0x9; - case 0x9: // state - rv=bit_position(lemm.s.state.raw); - switch (rv) { - case -2: - //FIXME : boucle bit par bit car ya parfois de multiple bits... - printf("state\t\t%04x -> %04x (multiple)\n",prevlemm.s.state.raw, lemm.s.state.raw); - break; - case -1: - printf("state\t\t%04x -> %04x (walking...)\n",prevlemm.s.state.raw, lemm.s.state.raw); - break; - default: - printf("state\t\t%04x -> %04x (%s)\n",prevlemm.s.state.raw, lemm.s.state.raw, state_str[rv]); - break; - } - break; - case 0xc: // spr_data_ptr - i=0xd; - case 0xd: // spr_data_ptr - printf("spr_data_ptr\t%04x -> %04x\n",prevlemm.s.spr_data_ptr, lemm.s.spr_data_ptr); - break; - case 0xe: // floattime_dble ? - printf("floattime_dble\t%02x -> %02x\n",prevlemm.s.floattime_dble, lemm.s.floattime_dble); - break; - case 0x14: // ptr2 ? - i=0x15; - case 0x15: // ptr2 ? - printf("ptr2\t\t%04x -> %04x\n",prevlemm.s.ptr2, lemm.s.ptr2); - break; - case 0x20: //expl_countdown - printf("expl_countdown\t%02x -> %02x\n",prevlemm.s.expl_countdown, lemm.s.expl_countdown); - break; - case 0x21: //steps_remain - printf("steps_remain\t%02x -> %02x\n",prevlemm.s.steps_remain, lemm.s.steps_remain); - break; - case 0x23: //falldist - printf("falldist\t%02x -> %02x\n",prevlemm.s.falldist, lemm.s.falldist); - break; - case 0x24: //flags1 - if ( prevlemm.s.flags1.bf.cap_climber != lemm.s.flags1.bf.cap_climber ) { - printf("cap_climber\t%2i -> %2i\n", prevlemm.s.flags1.bf.cap_climber, lemm.s.flags1.bf.cap_climber); - } else if ( prevlemm.s.flags1.bf.walk_pause_for_shruggling != lemm.s.flags1.bf.walk_pause_for_shruggling ) { - printf("walk_pause_for_shruggling\t%2i -> %2i\n", prevlemm.s.flags1.bf.walk_pause_for_shruggling, lemm.s.flags1.bf.walk_pause_for_shruggling); - } else { - printf("flags1.unknown\t%02x -> %02x\n",prevlemm.s.flags1.raw, lemm.s.flags1.raw); - } - break; - case 0x25: //cap_floater - printf("cap_floater\t%02x -> %02x\n",prevlemm.s.cap_floater, lemm.s.cap_floater); - break; - case 0x26: //is_gone - printf("is_gone\t%02x -> %02x\n",prevlemm.s.is_gone, lemm.s.is_gone); - break; - case 0x27: //direction - printf("direction\t%i -> %i\n",prevlemm.s.direction, lemm.s.direction); - break; - case 0x29: //draw_hint ? - printf("draw_hint\t\t%02x -> %02x (%s)\n",prevlemm.s.draw_hint, lemm.s.draw_hint, draw_hint_str[lemm.s.draw_hint]); - break; - default: - printf("(0x%02x)\t\t%02x -> %02x\n", i, prevlemm.raw[i], lemm.raw[i]); - } - } - similar_frames++; - } - rsp_quit(&rsp); - return 0; -} - diff --git a/src/dosbox_snif/main_dump_ds0.c b/src/dosbox_snif/main_dump_ds0.c deleted file mode 100644 index e54589d..0000000 --- a/src/dosbox_snif/main_dump_ds0.c +++ /dev/null @@ -1,61 +0,0 @@ -#include "rsp.h" -#include "rsp_lemm.h" -#include "utils.h" - -#include /* memset() */ -#include /* printf() */ - -int main(int argc, char *argv[]) { - int rv, i, end=0; - struct rsp_state rsp; - char ds_si[10], command[16]; - unsigned int addr, ds_offset; - - rv=rsp_lemm_init(&rsp, ds_si); - if ( rv != 0 ) { - printf("Error rsp_lemm_init() returns %i\n", rv); - return 1; - } - - while (!end) { - rsp_query(&rsp, "c"); // Continue - if ( rsp.replied != 1 ) printf("Bug 03\n"); - rsp_recv_full(&rsp); - if ( rsp_check_and_clear(&rsp, "S05") != 0 ) printf("Bug 04\n"); - - // For the beginning of the ds segment - ds_offset=0; - /* For this chunk of code : - 000052A3 83E307 and bx,byte +0x7 bx = 0x5660 + lemm.x_effective % 8; - 000052A6 81C36056 add bx,0x5660 // - 000052AA 8A27 mov ah,[bx] ah = [bx]; - */ - ds_offset = 0x5660; - /* For understanding pixel collision tests at 00005280 - di = lemm.y_effective - 16; - if ( di >= 0 ) di=0; //WTF ??? - di *= (LEVEL_WIDTH/8); - di += 0x6d60 + lemm.x_effective / 8; - */ - ds_offset = 0x6d60; - - ds_offset = 0x3f; - for (i=0;i<8;i++) { - addr = (0xb55 << 4) + ds_offset + (i * 0x20); - snprintf(command, 15, "m%06x,0x20", addr ); - rsp_query(&rsp, command); - if ( rsp_decode(&rsp) != 0x20 *2) { - printf("%06x : Bug\n", addr); - } else { - printf("%06x : %s\n", addr, rsp.decoded); - } - } - printf("\n"); - } - - - rsp_quit(&rsp); - return 0; -} - - diff --git a/src/dosbox_snif/main_poke.c b/src/dosbox_snif/main_poke.c deleted file mode 100644 index e0048fa..0000000 --- a/src/dosbox_snif/main_poke.c +++ /dev/null @@ -1,64 +0,0 @@ -#include "rsp.h" -#include "rsp_lemm.h" -#include "utils.h" - -#include /* memset() */ -#include /* printf() */ - -int main(int argc, char *argv[]) { - int rv, i, end_input, end_loop; - struct rsp_state rsp; - char ds_si[10], command[16], input[100]; - unsigned int poke_base, poke_off, poke_val; - - rv=rsp_lemm_init(&rsp, ds_si); - if ( rv != 0 ) { - printf("Error rsp_lemm_init() returns %i\n", rv); - return 1; - } - if ( sscanf(ds_si, "%x", &poke_base) != 1 ) printf("Bug 20\n");; - - end_loop=0; - while (!end_loop) { - rsp_query(&rsp, "c"); // Continue - if ( rsp.replied != 1 ) printf("Bug 03\n"); - rsp_recv_full(&rsp); - if ( rsp_check_and_clear(&rsp, "S05") != 0 ) printf("Bug 04\n"); - - snprintf(command, 15, "m%s,0x2d", ds_si); - rsp_query(&rsp, command); // Read a lemming record - if ( rsp_decode(&rsp) != 0x2d * 2 ) { - printf("Bug 07\n"); - } else { - for (i=0; rsp.decoded[i]!='\0'; i++) { - putchar(rsp.decoded[i]); - if (i%2==1) putchar(' '); - if (i%16==15) putchar(' '); - } - putchar('\n'); - } - - end_input=0; - do { - printf("address value ? "); fflush(stdout); - if ( fgets(input, 99, stdin) == NULL ) { - //printf("pb fgets\n"); - end_input=1; continue; - } - if ( sscanf(input,"%x %x", &poke_off, &poke_val) != 2 ) { - //printf("pb sscanf\n"); - end_input=1; continue; - } - if ( rsp_poke(&rsp, poke_base + poke_off, poke_val) != 0 ) { - printf("Bug 21\n"); - end_input=1; continue; - } - } while ( !end_input ); - } - - - rsp_quit(&rsp); - return 0; -} - - diff --git a/src/dosbox_snif/rsp.c b/src/dosbox_snif/rsp.c deleted file mode 100644 index c9957b7..0000000 --- a/src/dosbox_snif/rsp.c +++ /dev/null @@ -1,243 +0,0 @@ -#include "rsp.h" - -/* recv() */ -#include -#include - -#include /* memset(), strncmp() */ -#include /* perror(), fprintf(), snprintf(), sscanf() */ -#include /* malloc(), free() */ -#include /* close() */ -#include /* EAGAIN... */ - -void _rsp_sniff_garbage(struct rsp_state *rsp) { - int recvbytes, rv; - - // Sniff garbages before sending command - recvbytes = recv(rsp->sockfd, rsp->response, rsp->data_maxlen, MSG_DONTWAIT); - if ( recvbytes < 0 ) { - rv = errno; - if ( rv == EAGAIN || rv == EWOULDBLOCK ) { - /* No garbage found, that's a good news */ - } else { - LOG_DEBUG("! <-(error %i)\n", rv); - } - recvbytes=0; - } - rsp->response[recvbytes] = '\0'; - if ( recvbytes > 0 ) { - LOG_DEBUG("! <-'%s'\n",rsp->response); - } -} - -int rsp_recv_full(struct rsp_state *rsp) { - - int rv, error=0, complete=0, full=0, sentbytes; - ssize_t bufoldpos=0, bufpos=0; - char *bom=NULL, *eom=NULL, *ptr; - unsigned char c, cack='+'; - unsigned int computed_checksum, read_checksum; - - do { - rv = recv(rsp->sockfd, rsp->response + bufpos, rsp->data_maxlen - bufpos, 0); - if ( rv < 0 ) { - switch (errno) { - case EAGAIN: - continue; - default: - error=1; - continue; - } - } - if ( rv == 0 ) { - error=1; - continue; - } - - bufoldpos = bufpos; - bufpos += rv; - - if ( bom == NULL ) { - bom = memchr(rsp->response + bufoldpos, '$', bufpos - bufoldpos); - } - - if ( bom != NULL && eom == NULL ) { - eom = memchr(bom, '#', bufpos - (bom - rsp->response) ); - } - - complete = bom && eom && (eom+2) <= (rsp->response + bufpos); // 2 char checksum after EOM - full = (bufpos >= rsp->data_maxlen); - - } while (!error && !complete && !full); - - if (error) return 1; - if (full) return 2; - - rsp->response[bufpos]='\0'; - - c=eom[3]; - eom[3]='\0'; - LOG_DEBUG(" <- '%s'\n", rsp->response); - - if ( (eom+3) < (rsp->response + bufpos - 1)) { - eom[3]=c; - LOG_DEBUG("? <- '%s'\n", eom+3); - } - - - rsp->response_len = eom - bom - 1; - rsp->response_bom = bom; - rsp->response_eom = eom; - - computed_checksum=0; - for (ptr = bom+1; ptr < eom; ptr++) { - computed_checksum = (computed_checksum + ((unsigned char)*ptr) ) % 256; - } - - rv = sscanf(eom + 1, "%02x", &read_checksum); - if ( rv != 1 || computed_checksum != read_checksum) return 3; - - rsp->replied = 1; - - if (rsp->noackmode !=1) { - sentbytes = send(rsp->sockfd, &cack, 1, 0); - if ( sentbytes < 1 ) return 4; - LOG_DEBUG("-> '+'\n"); - } - - return 0; -} - -int rsp_init(int sockfd, int data_maxlen, struct rsp_state *rsp) { - memset(rsp,0,sizeof(struct rsp_state)); - rsp->sockfd = sockfd; - rsp->data_maxlen = data_maxlen; - - rsp->command = malloc(data_maxlen+1); - if ( rsp->command == NULL ) return 1; - - rsp->response = malloc(data_maxlen+1); - if ( rsp->response == NULL ) return 1; - - rsp->decoded = malloc(data_maxlen+1); - if ( rsp->decoded == NULL ) return 1; - -/* - rsp_query(rsp, "QStartNoAckMode"); - if ( rsp_check_and_clear(rsp, "OK") == 0 ) rsp->noackmode=1; -*/ - return 0; -} - -void rsp_quit(struct rsp_state *rsp) { - //rsp_query(rsp, "k"); - if ( rsp->command != NULL ) free(rsp->command); - if ( rsp->response != NULL ) free(rsp->response); - if ( rsp->decoded != NULL ) free(rsp->decoded); - close(rsp->sockfd); - memset(rsp,0,sizeof(struct rsp_state)); -} - -void rsp_send_break(struct rsp_state *rsp) { - int sentbytes; - char cbreak=3; - - rsp->replied = 0; - rsp->response_len = 0; - - _rsp_sniff_garbage(rsp); - - sentbytes = send(rsp->sockfd, &cbreak, 1, 0); - if ( sentbytes < 1 ) return; - LOG_DEBUG("-> '^C'\n"); - - rsp_recv_full(rsp); -} - -void rsp_query(struct rsp_state *rsp, char command[]) { - int sentbytes; - unsigned int checksum, i; - unsigned char c; - - - rsp->replied = 0; - rsp->response_len = 0; - - i=0; checksum=0; - while ( (c=command[i++]) != '\0' ) { - checksum = (checksum + c ) % 256; - } - - rsp->command_len = snprintf(rsp->command, rsp->data_maxlen, "$%s#%02x", command, checksum); - if (rsp->command_len < 5) return; - - _rsp_sniff_garbage(rsp); - - sentbytes = send(rsp->sockfd, rsp->command, rsp->command_len, 0); - if ( sentbytes < rsp->command_len ) return; - LOG_DEBUG("-> '%s'\n", rsp->command); - - - rsp_recv_full(rsp); -} - -int rsp_check_and_clear(struct rsp_state *rsp, char expected_response[]) { - - int expected_responselen = strlen(expected_response); - - if ( rsp->replied != 1 ) return 1; - rsp->replied = 0; - - if ( rsp->response_len < expected_responselen ) return 2; - if ( strncmp(rsp->response_bom + 1, expected_response, expected_responselen) != 0 ) return 3; - - return 0; -} - -int rsp_decode(struct rsp_state *rsp) { -/* -Response data can be run-length encoded to save space. Run-length encoding replaces runs of identical characters with one instance of the repeated character, followed by a ‘*’ and a repeat count. The repeat count is itself sent encoded, to avoid binary characters in data: a value of n is sent as n+29. For a repeat count greater or equal to 3, this produces a printable ascii character, e.g. a space (ascii code 32) for a repeat count of 3. (This is because run-length encoding starts to win for counts 3 or more.) Thus, for example, ‘0* ’ is a run-length encoding of “0000”: the space character after ‘*’ means repeat the leading 0 32 - 29 = 3 more times. - -The printable characters ‘#’ and ‘$’ or with a numeric value greater than 126 must not be used. Runs of six repeats (‘#’) or seven repeats (‘$’) can be expanded using a repeat count of only five (‘"’). For example, ‘00000000’ can be encoded as ‘0*"00’. -*/ - char src, *srcptr, *dstptr; - int repe, max; - - if ( rsp->replied != 1 ) return -1; - - dstptr = rsp->decoded; - for ( srcptr = rsp->response_bom+1; srcptr < rsp->response_eom; srcptr++ ) { - // FIXME : implemnt RLE decoding - src = *srcptr; - switch (src) { - case '*': - srcptr++; - repe=(*srcptr)-29; - if (repe < 2 ) return -1; - max = rsp->decoded + rsp->data_maxlen - 1 - dstptr; - if ( repe > max ) { repe = max; } - memset(dstptr, *(srcptr-2), repe); - dstptr += repe; - break; - default: - *(dstptr++) = *srcptr; - break; - } - } - *dstptr='\0'; - - return dstptr - rsp->decoded; -} - -int rsp_poke(struct rsp_state *rsp, unsigned int poke_addr, unsigned int poke_value) { - char command[16]; - printf("DEBUG : rsp_poke()\n"); - if ( snprintf(command, 15, "M %4x,2:%2x", poke_addr & 0xffff, poke_value & 0xff) < 11 ) return 1; - printf("DEBUG : command == '%s'\n", command); - rsp_query(rsp, command); // Send the poke command to GDB stub - printf("DEBUG : response == '%s'\n", rsp->response); - if ( rsp_check_and_clear(rsp, "OK") != 0 ) return 2; - - return 0; -} - diff --git a/src/dosbox_snif/rsp.h b/src/dosbox_snif/rsp.h deleted file mode 100644 index c8f1378..0000000 --- a/src/dosbox_snif/rsp.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef _RSP_H -#define _RSP_H - -#define LOG_DEBUG(...) -//#include -//#define LOG_DEBUG(...) printf(__VA_ARGS__) - -struct rsp_state { - int sockfd; - int data_maxlen; - int noackmode; - int replied; - int command_len, response_len; - char *command, *response, *decoded; /* Malloc'ed */ - char *response_bom, *response_eom; /* Just pointers on *response string */ -}; - -int rsp_init(int sockfd, int data_maxlen, struct rsp_state *rsp); -void rsp_quit(struct rsp_state *rsp); -void rsp_send_break(struct rsp_state *rsp); -void rsp_query(struct rsp_state *rsp, char command[]); -int rsp_check_and_clear(struct rsp_state *rsp, char expected_response[]); -int rsp_recv_full(struct rsp_state *rsp); -int rsp_decode(struct rsp_state *rsp); -int rsp_poke(struct rsp_state *rsp, unsigned int poke_addr, unsigned int poke_value); - -#endif /*_RSP_H*/ diff --git a/src/dosbox_snif/rsp_lemm.c b/src/dosbox_snif/rsp_lemm.c deleted file mode 100644 index e39ef30..0000000 --- a/src/dosbox_snif/rsp_lemm.c +++ /dev/null @@ -1,65 +0,0 @@ -#include "rsp_lemm.h" -#include "utils.h" - -#include /* memset(), strncmp() */ -#include /* printf() */ - -int rsp_lemm_init(struct rsp_state *rsp, char *ds_si) { - int rv; - int sockfd; - - memset(ds_si,'X',10); - ds_si[9]='\0'; - - rv = tcp_client_init(HOST, PORT, &sockfd); - if ( rv != 0 ) return rv; - - rsp_init(sockfd, MAXDATASIZE-1, rsp); - -/* - rsp_query(rsp, "qRcmd,666c61745f6569702c30"); //flat_eip,0 - if ( rsp_check_and_clear(rsp, "OK") != 0 ) printf("Bug\n"); -*/ - rsp_query(rsp, "?"); - if ( rsp_check_and_clear(rsp, "S05") != 0 ) { - // The program is not stopped - rsp_send_break(rsp); // Request to freeze the program - if ( rsp->replied != 1 ) return 10; - } - - rsp_query(rsp, "Z0,38C4,1"); // Set execution breakpoint at 0208:1844 (0x38C4) - if ( rsp_check_and_clear(rsp, "OK") != 0 ) return 11; - - do { - rsp_query(rsp, "c"); // Continue - if ( rsp->replied != 1 ) continue; //return 12; - rsp_recv_full(rsp); - if ( rsp_check_and_clear(rsp, "S05") != 0 ) continue; //return 13; -// (void) rsp_check_and_clear(rsp, "S05"); - - rsp_query(rsp, "p8"); // Read $eip (/!\ byte order. ex : $e4b0* !#76 ) -// if ( rsp_check_and_clear(rsp, "c4380000") != 0 ) return 14; - } while ( rsp_check_and_clear(rsp, "c4380000") != 0 ); - - rsp_query(rsp, "pc"); // Read $ds - if ( rsp_decode(rsp) <8 ) return 15; - ds_si[0]=rsp->decoded[2]; - ds_si[1]=rsp->decoded[3]; - ds_si[2]=rsp->decoded[0]; - ds_si[3]=rsp->decoded[1]; - ds_si[4]=':'; - - rsp_query(rsp, "p6"); // Read $si - if ( rsp_decode(rsp) <8 ) return 16; - ds_si[5]=rsp->decoded[2]; - ds_si[6]=rsp->decoded[3]; - ds_si[7]=rsp->decoded[0]; - ds_si[8]=rsp->decoded[1]; - - printf("ds:si == %s\n", ds_si); - flatten(ds_si); - printf("$ds_si == %s\n", ds_si); - - return 0; -} - diff --git a/src/dosbox_snif/rsp_lemm.h b/src/dosbox_snif/rsp_lemm.h deleted file mode 100644 index bd95d4f..0000000 --- a/src/dosbox_snif/rsp_lemm.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _RSP_LEMM_H -#define _RSP_LEMM_H - -#include "rsp.h" - -#define HOST "localhost" -#define PORT "1234" -#define MAXDATASIZE 1400 - - -int rsp_lemm_init(struct rsp_state *rsp, char *ds_si); - -#endif /*_RSP_LEMM_H*/ diff --git a/src/dosbox_snif/utils.c b/src/dosbox_snif/utils.c deleted file mode 100644 index 8e26d46..0000000 --- a/src/dosbox_snif/utils.c +++ /dev/null @@ -1,112 +0,0 @@ -#include "utils.h" - -/* socket() */ -#include -#include -#include -/* getaddrinfo() */ -#include -#include -/* inet_ntop() */ -#include -#define GET_SOCK_IN_ADDR(sa) (((struct sockaddr*)sa)->sa_family == AF_INET)?(void *)&(((struct sockaddr_in*)sa)->sin_addr):(void *)&(((struct sockaddr_in6*)sa)->sin6_addr) - -#include /* memset(), strncmp() */ -#include /* perror(), fprintf(), snprintf(), sscanf() */ -#include /* malloc(), free() */ -#include /* close() */ -#include /* EAGAIN... */ - - -int tcp_client_init(char host[], char port[], int *sockfd) { - int rv, flag=1; - char s[INET6_ADDRSTRLEN]; - struct addrinfo hints, *servinfo, *p; - memset(&hints,0,sizeof(struct addrinfo)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - - if ((rv = getaddrinfo(host, port, &hints, &servinfo)) != 0) { - fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); - return 1; - } - - - // loop through all the results and connect to the first we can - for(p = servinfo; p != NULL; p = p->ai_next) { - if ((*sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) { - //perror("client: socket"); - continue; - } - - if ( setsockopt(*sockfd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(flag)) != 0 ) { - perror("client: setsockopt TCP_NODELAY"); - } - - if (connect(*sockfd, p->ai_addr, p->ai_addrlen) == -1) { - close(*sockfd); - //perror("client: connect"); - continue; - } - - break; - } - - freeaddrinfo(servinfo); - - if (p == NULL) { - fprintf(stderr, "client: failed to connect\n"); - return 2; - } - - inet_ntop(p->ai_family, GET_SOCK_IN_ADDR(p->ai_addr), s, sizeof s); - printf("client: connecting to %s\n", s); - - return 0; -} - -void flatten(char *seg_off) { - unsigned int seg=0, off=0, flat; - sscanf(seg_off, "%4x", &seg); - sscanf(seg_off+5, "%4x", &off); - flat= (seg<<4) + off; - snprintf(seg_off, 9, "%x", flat); -} - - -int hexascii2bin(char src[], void *dst, int maxlen) { - int i; - unsigned char offset; - for (i=0; i= '0' && src[i] <= '9' ) offset='0'; - else if ( src[i] >= 'a' && src[i] <= 'f' ) offset='a' - 10; - else if ( src[i] >= 'A' && src[i] <= 'F' ) offset='A' - 10; - else break; - - if ( i % 2 == 0 ) { - ((unsigned char *)dst)[i/2] = (src[i]-offset) << 4; - } else { - ((unsigned char *)dst)[i/2] += (src[i]-offset); - } - } - return i/2; -} - -// Indicate the position of the bit that is on -// If multiple bits activated, returns -2 -// If no bits activated, return -1 -int bit_position(uint16_t flags) { - int i, pos; - pos=-1; // Not found yet - for (i=0;i<16;i++) { - if ( (flags >> i) & 0x0001 ) { - if ( pos == -1 ) { - pos=i; - } else { - return -2; - } - } - } - return pos; -} diff --git a/src/dosbox_snif/utils.h b/src/dosbox_snif/utils.h deleted file mode 100644 index a7031a8..0000000 --- a/src/dosbox_snif/utils.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef _UTILS_H -#define _UTILS_H - -#include - -int tcp_client_init(char host[], char port[], int *sockfd); -void flatten(char *seg_off); -int hexascii2bin(char src[], void *dst, int maxlen); -int bit_position(uint16_t flags); - -#endif /*_UTIL_H*/ -- cgit v1.2.3