mirror of
https://github.com/mid-kid/metroskrew.git
synced 2025-06-18 13:15:40 -04:00
Decompile most of the code involved in generating dep files
This commit is contained in:
parent
e2e96737b9
commit
6a04657b6f
@ -1,8 +1,9 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "include.h"
|
||||
|
||||
// This function mallocs some memory without clearing it, and reads from it,
|
||||
// which causes the behavior (and compilation output) to depend on it.
|
||||
//
|
||||
@ -11,22 +12,6 @@
|
||||
|
||||
#define SKREW_HACK01
|
||||
|
||||
struct STRUC_0063a828 {
|
||||
struct STRUC_0063a828 *next;
|
||||
int _unk1[1];
|
||||
struct STRUC_0063a828 *unk_8;
|
||||
struct STRUC_0063a828 *unk_c;
|
||||
int _unk2[3];
|
||||
int unk_1c;
|
||||
};
|
||||
|
||||
extern int DAT_0063a798; // 0x0063a798
|
||||
extern struct STRUC_0063a828 *DAT_0063a828;
|
||||
extern struct STRUC_0063a828 **DAT_0063ccb0;
|
||||
extern uint32_t **DAT_0063ccf0; // 0x0063ccf0
|
||||
|
||||
void *prog_malloc(size_t size); // 0x00442550
|
||||
void FUN_004f8b60(void);
|
||||
void bitarr_cpy(uint32_t *dst, uint32_t *src, int len); // 0x00581750
|
||||
int bitarr_cpycmp(uint32_t *dst, uint32_t *src, int len); // 0x00581790
|
||||
void bitarr_set(uint32_t *dst, int len, uint32_t val); // 0x005817d0
|
||||
|
150
patch/depfile_build.c
Normal file
150
patch/depfile_build.c
Normal file
@ -0,0 +1,150 @@
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "include.h"
|
||||
|
||||
__stdcall char *depfile_get_target(char *path, char *dir, char *dest, unsigned dest_size); // 0x004178f0
|
||||
|
||||
// TODO
|
||||
__cdecl void depfile_get_header(char *param_1, int param_2, char *param_3); // 0x0043c010
|
||||
__stdcall char *path_join(char *src, char *dst, size_t size); // 0x004110f0
|
||||
|
||||
// 0x00411b90
|
||||
__stdcall int string_alloc(unsigned size, mwstring *string)
|
||||
{
|
||||
string->data = GlobalAlloc(GMEM_ZEROINIT, size);
|
||||
string->size = size;
|
||||
if (!string->data) return my_GetLastError();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 0x00411bc0
|
||||
__stdcall int string_realloc(mwstring *string, unsigned size)
|
||||
{
|
||||
char *data = GlobalReAlloc(string->data, size, GMEM_ZEROINIT | GMEM_MOVEABLE);
|
||||
if (!data) {
|
||||
string->data = NULL;
|
||||
string->size = 0;
|
||||
return my_GetLastError();
|
||||
}
|
||||
string->data = data;
|
||||
string->size = size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 0x00411c00
|
||||
__stdcall char *string_data(mwstring *string)
|
||||
{
|
||||
if (GlobalFlags(string->data) == GMEM_INVALID_HANDLE) {
|
||||
return NULL;
|
||||
}
|
||||
return string->data;
|
||||
}
|
||||
|
||||
// 0x00411c80
|
||||
__stdcall int string_size(mwstring *string, unsigned *out)
|
||||
{
|
||||
if (GlobalFlags(string->data) == GMEM_INVALID_HANDLE) {
|
||||
*out = 0;
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
}
|
||||
*out = string->size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 0x00417ea0
|
||||
__stdcall int string_append(mwstring *string, char *data, unsigned size)
|
||||
{
|
||||
int rv;
|
||||
|
||||
unsigned cur_size;
|
||||
rv = string_size(string, &cur_size);
|
||||
if (rv) return rv;
|
||||
|
||||
rv = string_realloc(string, cur_size + size);
|
||||
if (rv) return rv;
|
||||
|
||||
char *cur_data = string_data(string);
|
||||
if (cur_data != NULL) {
|
||||
memcpy(cur_data + cur_size, data, size);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 0x0043c880
|
||||
__cdecl char *depfile_escape_spaces(int doit, char *dst, char *src)
|
||||
{
|
||||
char *s = src;
|
||||
char *d = dst;
|
||||
|
||||
if (!doit) return src;
|
||||
|
||||
while (*s) {
|
||||
if (*s == ' ') *d++ = '\\';
|
||||
*d++ = *src++;
|
||||
}
|
||||
*d = '\0';
|
||||
return dst;
|
||||
}
|
||||
|
||||
// 0x0043c8d0
|
||||
__cdecl void depfile_build(char *header_struct, char *depfile_struct, mwstring *string)
|
||||
{
|
||||
int cur_header, num_headers;
|
||||
char strbuf[PATH_MAX * 2];
|
||||
char escape_buf[PATH_MAX * 2 - 4];
|
||||
|
||||
if (string_alloc(0, string)) goto outofmem;
|
||||
|
||||
num_headers = *(int *)(depfile_struct + 0x870);
|
||||
|
||||
char target[PATH_MAX];
|
||||
depfile_get_target(depfile_struct + 0x423, NULL, target, PATH_MAX);
|
||||
|
||||
if (!*target) {
|
||||
char *source = depfile_struct + 0x1c;
|
||||
char *source_escaped = depfile_escape_spaces(
|
||||
strchr(source, ' ') != NULL, escape_buf, source);
|
||||
|
||||
sprintf(strbuf, "%s: %s\n", source_escaped, num_headers ? "\\" : "");
|
||||
if (string_append(string, strbuf, strlen(strbuf))) goto outofmem;
|
||||
} else {
|
||||
char *target_escaped = depfile_escape_spaces(
|
||||
strchr(target, ' ') != NULL, escape_buf, target);
|
||||
|
||||
sprintf(strbuf, "%s: ", target_escaped);
|
||||
if (string_append(string, strbuf, strlen(strbuf))) goto outofmem;
|
||||
|
||||
char *source = depfile_struct + 0x1c;
|
||||
char *source_escaped = depfile_escape_spaces(
|
||||
strchr(source, ' ') != NULL, escape_buf, source);
|
||||
|
||||
sprintf(strbuf, "%s %s\n", source_escaped, num_headers ? "\\" : "");
|
||||
if (string_append(string, strbuf, strlen(strbuf))) goto outofmem;
|
||||
}
|
||||
|
||||
for (cur_header = 0; cur_header < *(int *)(depfile_struct + 0x870);
|
||||
cur_header++) {
|
||||
num_headers--;
|
||||
|
||||
char header[PATH_MAX * 2 - 4];
|
||||
char header_full[PATH_MAX];
|
||||
|
||||
depfile_get_header(header_struct,
|
||||
(*(int **)(depfile_struct + 0x878))[cur_header], header);
|
||||
path_join(header, header_full, PATH_MAX);
|
||||
|
||||
char *header_escaped = depfile_escape_spaces(
|
||||
strchr(header_full, ' ') != NULL, escape_buf, header_full);
|
||||
|
||||
sprintf(strbuf, "\t%s %s\n", header_escaped, num_headers ? "\\" : "");
|
||||
if (string_append(string, strbuf, strlen(strbuf))) goto outofmem;
|
||||
}
|
||||
return;
|
||||
|
||||
outofmem:
|
||||
fprintf(stderr, "\n*** Out of memory\n");
|
||||
exit(233);
|
||||
}
|
@ -61,4 +61,11 @@ addr_DAT_0063ccb0 = 0x63ccb0
|
||||
|
||||
addr_DAT_0063ccf0 = 0x63ccf0
|
||||
|
||||
addr_depfile_build = 0x0043c8d0
|
||||
code_depfile_build = addr_depfile_build - pe_text_addr + pe_text_off
|
||||
code_depfile_build.end = code_depfile_build + 10
|
||||
addr_depfile_get_target = 0x004178f0
|
||||
addr_depfile_get_header = 0x0043c010
|
||||
addr_path_join = 0x004110f0
|
||||
|
||||
.include "patch.i"
|
||||
|
32
patch/include.h
Normal file
32
patch/include.h
Normal file
@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// WINE headers
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
DWORD WINAPI my_GetLastError(void);
|
||||
|
||||
#define PATH_MAX 0x104
|
||||
|
||||
struct STRUC_0063a828 {
|
||||
struct STRUC_0063a828 *next;
|
||||
int _unk1[1];
|
||||
struct STRUC_0063a828 *unk_8;
|
||||
struct STRUC_0063a828 *unk_c;
|
||||
int _unk2[3];
|
||||
int unk_1c;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
char *data;
|
||||
unsigned size;
|
||||
} mwstring;
|
||||
|
||||
extern int DAT_0063a798; // 0x0063a798
|
||||
extern struct STRUC_0063a828 *DAT_0063a828; // 0x0063a828
|
||||
extern struct STRUC_0063a828 **DAT_0063ccb0; // 0x0063ccb0
|
||||
extern uint32_t **DAT_0063ccf0; // 0x0063ccf0
|
||||
|
||||
__cdecl void *prog_malloc(size_t size); // 0x00442550
|
||||
__cdecl void FUN_004f8b60(void); // 0x004f8b60
|
@ -4,7 +4,8 @@ fs = import('fs')
|
||||
|
||||
sources_c = [
|
||||
'env.c',
|
||||
'FUN_00505340.c'
|
||||
'FUN_00505340.c',
|
||||
'depfile_build.c'
|
||||
]
|
||||
|
||||
c_args = [
|
||||
@ -15,7 +16,8 @@ c_args = [
|
||||
]
|
||||
|
||||
patch_common = static_library('patch_common', sources_c,
|
||||
c_args: c_args)
|
||||
c_args: c_args,
|
||||
dependencies: wine_headers)
|
||||
|
||||
# Patch listing
|
||||
|
||||
|
@ -53,17 +53,14 @@ incbin patch.end, (pe_text_off + pe_text_len - patch.end)
|
||||
wjmp patch_getenv
|
||||
.endm
|
||||
|
||||
.macro patch_memreuse01_hook
|
||||
call jump_patch_memreuse01_hook
|
||||
.endm
|
||||
.macro patch_memreuse01_exit
|
||||
jmp jump_patch_memreuse01_exit
|
||||
.endm
|
||||
|
||||
.macro patch_FUN_00505340
|
||||
wjmp FUN_00505340
|
||||
.endm
|
||||
|
||||
.macro patch_depfile_build
|
||||
wjmp depfile_build
|
||||
.endm
|
||||
|
||||
# The actual code
|
||||
.section .patch_pe_text, "ax"
|
||||
pe_text:
|
||||
@ -72,34 +69,21 @@ pe_text:
|
||||
patch code_init_args, patch_init_args
|
||||
patch code_init_envp, patch_init_envp
|
||||
patch code_getenv, patch_getenv
|
||||
.ifdef code_memreuse01
|
||||
#patch code_memreuse01_hook, patch_memreuse01_hook
|
||||
#patch code_memreuse01_exit, patch_memreuse01_exit
|
||||
.ifdef code_depfile_build
|
||||
patch code_depfile_build, patch_depfile_build
|
||||
.endif
|
||||
.ifdef code_FUN_00505340
|
||||
patch code_FUN_00505340, patch_FUN_00505340
|
||||
.endif
|
||||
patch_end
|
||||
|
||||
.ifdef code_memreuse01
|
||||
jump_patch_memreuse01:
|
||||
wcall patch_memreuse01_hook
|
||||
lea ecx, [ebx + 0x1f]
|
||||
sar ecx, 5
|
||||
lea ecx, [ecx * 4]
|
||||
ret
|
||||
jump_patch_memreuse01_exit:
|
||||
wcall patch_memreuse01_exit
|
||||
add esp, 8
|
||||
pop ebp
|
||||
pop edi
|
||||
pop esi
|
||||
pop ebx
|
||||
ret
|
||||
.endif
|
||||
|
||||
var prog_malloc addr_prog_malloc
|
||||
var FUN_004f8b60 addr_FUN_004f8b60
|
||||
.ifdef code_depfile_build
|
||||
var depfile_get_target addr_depfile_get_target
|
||||
var depfile_get_header addr_depfile_get_header
|
||||
var path_join addr_path_join
|
||||
.endif
|
||||
|
||||
var DAT_0063a798 addr_DAT_0063a798
|
||||
var DAT_0063a828 addr_DAT_0063a828
|
||||
|
30
patch/scan.c
30
patch/scan.c
@ -356,6 +356,35 @@ unsigned find_memreuse01(const struct file *binary, const struct loc **res)
|
||||
return 7;
|
||||
}
|
||||
|
||||
unsigned find_depfile(const struct file *binary, const struct loc **res)
|
||||
{
|
||||
const struct scan code[] = {
|
||||
DEF_SCAN(0,
|
||||
0x53, // push ebx
|
||||
0x56, // push esi
|
||||
0x57, // push edi
|
||||
0x55, // push ebp
|
||||
0x81, 0xec, 0x1c, 0x08, 0x00, 0x00, // sub esp, 0x81c
|
||||
0x8b, 0x9c, 0x24, 0x34, 0x08, 0x00, 0x00 // mov ebx, dword ptr [esp + u32]
|
||||
),
|
||||
END_SCAN
|
||||
};
|
||||
|
||||
static struct loc loc[] = {
|
||||
{.name = "depfile_build"},
|
||||
};
|
||||
|
||||
const unsigned char *pos = scan(binary, code, 0);
|
||||
if (!pos) return 0;
|
||||
size_t off = pos - binary->data;
|
||||
|
||||
loc[0].start = off + code[0].off;
|
||||
loc[0].end = off + code[0].off + code[0].size;
|
||||
|
||||
*res = loc;
|
||||
return 1;
|
||||
}
|
||||
|
||||
typedef unsigned (*funcs_t)(const struct file *, const struct loc **);
|
||||
static const funcs_t funcs[] = {
|
||||
find_fs,
|
||||
@ -363,6 +392,7 @@ static const funcs_t funcs[] = {
|
||||
find_getenv,
|
||||
find_findexe,
|
||||
find_memreuse01,
|
||||
find_depfile,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user