summaryrefslogtreecommitdiff
path: root/reverse-engineering/dosbox_snif/main_validate_code.c
blob: 22ce62d5a4006e1546de64eb7a94686394048967 (plain)
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
#include "dos_lemm.h"
#include "dos_lemm_sim.h"
#include "rsp.h"
#include "rsp_lemm.h"
#include "utils.h"

#include <string.h> /* memset() */
#include <stdio.h> /* printf() */

inline int imin(int a, int b) {
	if ( a < b ) return a;
	return b;
}

int main(int argc, char *argv[]) {
	int rv, i, end=0, byte, loops;
	struct rsp_state rsp;
	char ds_si[10], command[16], hex_byte[3];
	unsigned int addr, size, offset;
	unsigned int bs=0x100; /* RSP memdump block size */

	struct game_data g_before, g_after, g_simulated, *g;

	hex_byte[2]='\0';

	rv=rsp_lemm_init(&rsp, ds_si);
	if ( rv != 0 ) {
		printf("Error rsp_lemm_init() returns %i\n", rv);
		return 1;
	}

	rsp_query(&rsp, "Z0,2F7B,1"); // Set execution breakpoint at 0208:0EFB (0x2F7B, return point of move_lemmings() )
	if ( rsp_check_and_clear(&rsp, "OK") != 0 ) {
		printf("Error when setting addition breakpoint\n");
		return 1;
	}

	loops=0;
	while (!end) {
		loops++;
		rsp_query(&rsp, "c"); // Continue
		if ( rsp.replied != 1 ) {
			printf("Bug 03\n");
			continue;
		}
		rsp_recv_full(&rsp);
		if ( rsp_check_and_clear(&rsp, "S05") != 0 ) {
			printf("Bug 04\n");
			continue;
		}

		rsp_query(&rsp, "p8"); // Read $eip
		if ( rsp_check_and_clear(&rsp, "c4380000") ) {
			g = &g_before;
		} else {
			g = &g_after;
		}

		//printf("sizeof(struct game_data) == %i\n", sizeof(struct game_data) );

		for (offset=0 ; offset < sizeof(struct game_data) ; offset += size) {
			size = imin(bs,sizeof(struct game_data)-offset);
			addr = (0xb55 << 4) + offset;
			snprintf(command, 15, "m%06x,0x%x", addr, size);
			//printf("-> %s\n", command);
			rsp_query(&rsp, command);
			if ( rsp_decode(&rsp) != size*2) {
				printf("%06x : Bug\n", addr);
				break;
			}

			//printf("%06x : %s\n", addr, rsp.decoded);
			for (i=0;i<size;i++) {
				memcpy(hex_byte, rsp.decoded+(i*2), 2);
				if ( sscanf(hex_byte, "%x", &byte) != 1 ) {
					printf("Bug decode\n");
					break;
				}
				((char *)g)[offset+i] = byte;
				//printf("((char *)&g)[0x%02x] = 0x%02x\n", offset+i, byte);
			}
		}
		//printf("\n");

		if ( g == &g_before ) {
			// Exec simulation
			memcpy(&g_simulated,&g_before,sizeof(struct game_data));
			move_lemmings(&g_simulated);
		} else {
			// Compare simulation results and orignal code results
			if ( game_data_diff(&g_simulated, &g_after) != 0 ) {
				(void) scanf("%s");
			}
		}

	}

	rsp_quit(&rsp);
	return 0;
}