Bemanitools v5.26 release

This commit is contained in:
icex2
2019-09-27 22:36:50 +02:00
commit cbd7720349
718 changed files with 62731 additions and 0 deletions
+23
View File
@@ -0,0 +1,23 @@
avsexes += launcher
rc_launcher := launcher.rc
ldflags_launcher := \
-mconsole \
deplibs_launcher := \
avs \
avs-ea3 \
libs_launcher := \
hook \
util \
src_launcher := \
avs-context.c \
ea3-config.c \
main.c \
module.c \
options.c \
property.c \
stubs.c \
+60
View File
@@ -0,0 +1,60 @@
#include <windows.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include "imports/avs.h"
#include "launcher/avs-context.h"
#include "util/log.h"
static void *avs_heap;
#ifdef AVS_HAS_STD_HEAP
static void *std_heap;
#endif
void avs_context_init(struct property_node *config,
uint32_t avs_heap_size, uint32_t std_heap_size,
avs_log_writer_t log_writer, void *log_writer_ctx)
{
avs_heap = VirtualAlloc(NULL, avs_heap_size, MEM_RESERVE | MEM_COMMIT,
PAGE_READWRITE);
if (avs_heap == NULL) {
log_fatal("Failed to VirtualAlloc %d byte AVS heap: %08x",
avs_heap_size, (unsigned int) GetLastError());
}
#ifdef AVS_HAS_STD_HEAP
std_heap = VirtualAlloc(NULL, std_heap_size, MEM_RESERVE | MEM_COMMIT,
PAGE_READWRITE);
if (std_heap == NULL) {
log_fatal("Failed to VirtualAlloc %d byte \"std\" heap: %08x",
std_heap_size, (unsigned int) GetLastError());
}
#endif
#ifdef AVS_HAS_STD_HEAP
avs_boot(config, std_heap, std_heap_size, avs_heap, avs_heap_size,
log_writer, log_writer_ctx);
#else
/* AVS v2.16.xx and I suppose onward uses a unified heap */
avs_boot(config, avs_heap, avs_heap_size, NULL, log_writer, log_writer_ctx);
#endif
}
void avs_context_fini(void)
{
avs_shutdown();
#ifdef AVS_HAS_STD_HEAP
VirtualFree(std_heap, 0, MEM_RELEASE);
#endif
VirtualFree(avs_heap, 0, MEM_RELEASE);
}
+17
View File
@@ -0,0 +1,17 @@
#ifndef LAUNCHER_AVS_CONTEXT_H
#define LAUNCHER_AVS_CONTEXT_H
#include <stdint.h>
#include "imports/avs.h"
#if AVS_VERSION < 1600
#define AVS_HAS_STD_HEAP
#endif
void avs_context_init(struct property_node *config,
uint32_t avs_heap_size, uint32_t std_heap_size,
avs_log_writer_t log_writer, void *log_writer_ctx);
void avs_context_fini(void);
#endif
+122
View File
@@ -0,0 +1,122 @@
#include <string.h>
#include "imports/avs.h"
#include "launcher/ea3-config.h"
#include "launcher/module.h"
#include "util/defs.h"
#include "util/hex.h"
#include "util/log.h"
#include "util/str.h"
PSMAP_BEGIN(ea3_ident_psmap)
PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct ea3_ident, softid,"/ea3/id/softid","")
PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct ea3_ident, hardid,"/ea3/id/hardid","")
PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct ea3_ident, pcbid, "/ea3/id/pcbid", "")
PSMAP_REQUIRED(PSMAP_TYPE_STR, struct ea3_ident, model, "/ea3/soft/model")
PSMAP_REQUIRED(PSMAP_TYPE_STR, struct ea3_ident, dest, "/ea3/soft/dest")
PSMAP_REQUIRED(PSMAP_TYPE_STR, struct ea3_ident, spec, "/ea3/soft/spec")
PSMAP_REQUIRED(PSMAP_TYPE_STR, struct ea3_ident, rev, "/ea3/soft/rev")
PSMAP_REQUIRED(PSMAP_TYPE_STR, struct ea3_ident, ext, "/ea3/soft/ext")
PSMAP_END
void ea3_ident_init(struct ea3_ident *ident)
{
memset(ident, 0, sizeof(*ident));
}
bool ea3_ident_from_property(struct ea3_ident *ident,
struct property *ea3_config)
{
return property_psmap_import(ea3_config, NULL, ident, ea3_ident_psmap);
}
void ea3_ident_hardid_from_ethernet(struct ea3_ident *ident)
{
struct avs_net_interface netif;
int result;
result = avs_net_ctrl(1, &netif, sizeof(netif));
if (result < 0) {
log_fatal("avs_net_ctrl call to get MAC address returned error: %d",
result);
}
ident->hardid[0] = '0';
ident->hardid[1] = '1';
ident->hardid[2] = '0';
ident->hardid[3] = '0';
hex_encode_uc(netif.mac_addr, sizeof(netif.mac_addr),
ident->hardid + 4, sizeof(ident->hardid) - 4);
}
bool ea3_ident_invoke_module_init(struct ea3_ident *ident,
const struct module_context *module, struct property_node *app_config)
{
char sidcode_short[17];
char sidcode_long[21];
char security_code[9];
bool ok;
/* Set up security env vars */
str_format(security_code, lengthof(security_code), "G*%s%s%s%s",
ident->model, ident->dest, ident->spec, ident->rev);
std_setenv("/env/boot/version", "0.0.0");
std_setenv("/env/profile/security_code", security_code);
std_setenv("/env/profile/system_id", ident->pcbid);
std_setenv("/env/profile/account_id", ident->pcbid);
std_setenv("/env/profile/license_id", ident->softid);
std_setenv("/env/profile/software_id", ident->softid);
std_setenv("/env/profile/hardware_id", ident->hardid);
/* Set up the short sidcode string, let dll_entry_init mangle it */
str_format(sidcode_short, lengthof(sidcode_short), "%s%s%s%s%s",
ident->model, ident->dest, ident->spec, ident->rev, ident->ext);
ok = module_context_invoke_init(module, sidcode_short, app_config);
if (!ok) {
return false;
}
/* Back-propagate sidcode */
memcpy(ident->model, sidcode_short + 0, sizeof(ident->model) - 1);
ident->dest[0] = sidcode_short[3];
ident->spec[0] = sidcode_short[4];
ident->rev[0] = sidcode_short[5];
memcpy(ident->ext, sidcode_short + 6, sizeof(ident->ext));
/* Set up long-form sidcode env var */
str_format(sidcode_long, lengthof(sidcode_long), "%s:%s:%s:%s:%s",
ident->model, ident->dest, ident->spec, ident->rev, ident->ext);
std_setenv("/env/profile/soft_id_code", sidcode_long);
return true;
}
void ea3_ident_to_property(const struct ea3_ident *ident,
struct property *ea3_config)
{
struct property_node *node;
int i;
for (i = 0 ; ea3_ident_psmap[i].type != 0xFF ; i++) {
node = property_search(ea3_config, 0, ea3_ident_psmap[i].path);
if (node != NULL) {
property_node_remove(node);
}
}
property_psmap_export(ea3_config, NULL, ident, ea3_ident_psmap);
}
+40
View File
@@ -0,0 +1,40 @@
#ifndef LAUNCHER_EA3_CONFIG_H
#define LAUNCHER_EA3_CONFIG_H
#include "imports/avs.h"
#include "launcher/module.h"
/* N.B. even though this might look like a Konami ABI, this is purely an
internal data structure. */
struct ea3_ident {
/* psmapped structure offset can't be zero for some stupid reason */
uint32_t dummy;
/* Initialized from ea3-config.xml, then fed back from sidcode_short */
char model[4];
char dest[4];
char spec[4];
char rev[4];
char ext[11];
/* Initialized from ea3-config.xml (hardware_id defaults to MAC addr) */
char softid[24];
char hardid[24];
char pcbid[24];
};
void ea3_ident_init(struct ea3_ident *ident);
bool ea3_ident_from_property(struct ea3_ident *ident,
struct property *ea3_config);
void ea3_ident_hardid_from_ethernet(struct ea3_ident *ident);
bool ea3_ident_invoke_module_init(struct ea3_ident *ident,
const struct module_context *module, struct property_node *app_config);
void ea3_ident_to_property(const struct ea3_ident *ident,
struct property *ea3_config);
#endif
+10
View File
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="requireAdministrator" />
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
+2
View File
@@ -0,0 +1,2 @@
#include <winuser.h>
1 RT_MANIFEST launcher.exe.manifest
+276
View File
@@ -0,0 +1,276 @@
#include <windows.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include "imports/avs.h"
#include "imports/avs-ea3.h"
#include "launcher/avs-context.h"
#include "launcher/ea3-config.h"
#include "launcher/module.h"
#include "launcher/options.h"
#include "launcher/property.h"
#include "launcher/stubs.h"
#include "util/defs.h"
#include "util/log.h"
#include "util/mem.h"
#include "util/str.h"
#include "util/codepage.h"
/* Gratuitous API changes orz */
static AVS_LOG_WRITER(log_callback, chars, nchars, ctx)
{
wchar_t *utf16;
char *utf8;
int utf16_len;
int utf8_len;
int result;
DWORD nwritten;
HANDLE console;
HANDLE file;
/* Ignore existing NUL terminator */
nchars--;
/* Transcode shit_jis to UTF-8 */
utf16_len = MultiByteToWideChar(CP_SHIFT_JIS, 0, chars, nchars, NULL, 0);
if (utf16_len == 0) {
abort();
}
utf16 = xmalloc(sizeof(*utf16) * utf16_len);
result = MultiByteToWideChar(CP_SHIFT_JIS, 0, chars, nchars, utf16,
utf16_len);
if (result == 0) {
abort();
}
utf8_len = WideCharToMultiByte(CP_UTF8, 0, utf16, utf16_len, NULL, 0,
NULL, NULL);
if (utf8_len == 0) {
abort();
}
utf8 = xmalloc(utf8_len + 2);
result = WideCharToMultiByte(CP_UTF8, 0, utf16, utf16_len, utf8, utf8_len,
NULL, NULL);
if (result == 0) {
abort();
}
#if AVS_VERSION >= 1500
utf8[utf8_len + 0] = '\r';
utf8[utf8_len + 1] = '\n';
utf8_len += 2;
#endif
/* Write to console and log file */
file = (HANDLE) ctx;
console = GetStdHandle(STD_OUTPUT_HANDLE);
if (ctx != INVALID_HANDLE_VALUE) {
WriteFile(file, utf8, utf8_len, &nwritten, NULL);
}
WriteFile(console, utf8, utf8_len, &nwritten, NULL);
/* Clean up */
free(utf8);
free(utf16);
}
int main(int argc, const char **argv)
{
int i;
const char *hook_dll;
bool ok;
HANDLE logfile;
struct ea3_ident ea3;
struct module_context module;
struct options options;
struct property *app_config;
struct property *avs_config;
struct property *ea3_config;
struct property_node *app_config_root;
struct property_node *avs_config_root;
struct property_node *ea3_config_root;
log_to_writer(log_writer_file, stdout);
/* Read command line */
options_init(&options);
if (!options_read_cmdline(&options, argc, argv)) {
options_print_usage();
return EXIT_FAILURE;
}
/* If enabled, wait for a remote debugger to attach. Spawning launcher
with a debugger crashes it for some reason (e.g. on jubeat08). However,
starting the launcher separately and attaching a remote debugger works */
if (options.remote_debugger) {
log_info("Waiting until debugger attaches to remote process...");
while (true) {
BOOL res = FALSE;
if (!CheckRemoteDebuggerPresent(GetCurrentProcess(), &res)) {
log_fatal("CheckRemoteDebuggerPresent failed: %08x",
(unsigned int) GetLastError());
}
if (res) {
log_info("Debugger attached, resuming");
break;
}
Sleep(1000);
}
}
/* Start up AVS */
if (options.logfile != NULL) {
logfile = CreateFileA(options.logfile, GENERIC_WRITE, FILE_SHARE_READ,
NULL, CREATE_ALWAYS, 0, NULL);
} else {
logfile = INVALID_HANDLE_VALUE;
}
avs_config = boot_property_load(options.avs_config_path);
avs_config_root = property_search(avs_config, 0, "/config");
if (avs_config_root == NULL) {
log_fatal("%s: /config missing", options.avs_config_path);
}
avs_context_init(avs_config_root,
options.avs_heap_size, options.std_heap_size,
log_callback, logfile);
boot_property_free(avs_config);
log_to_external(log_body_misc, log_body_info, log_body_warning,
log_body_fatal);
/* Load game DLL */
module_context_init(&module, options.module);
/* Load hook DLLs */
for (i = 0 ; i < options.hook_dlls.nitems ; i++) {
hook_dll = *array_item(char *, &options.hook_dlls, i);
if (LoadLibraryA(hook_dll) == NULL) {
LPSTR buffer;
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR) &buffer, 0, NULL);
log_fatal("%s: Failed to load hook DLL: %s", hook_dll, buffer);
LocalFree(buffer);
}
}
/* Inject GetModuleHandle hooks */
stubs_init();
/* Prepare ea3 config */
ea3_config = boot_property_load(options.ea3_config_path);
ea3_config_root = property_search(ea3_config, 0, "/ea3");
if (ea3_config_root == NULL) {
log_fatal("%s: /ea3 missing", options.ea3_config_path);
}
ea3_ident_init(&ea3);
if (!ea3_ident_from_property(&ea3, ea3_config)) {
log_fatal("%s: Error reading IDs from config file",
options.ea3_config_path);
}
if (options.softid != NULL) {
str_cpy(ea3.softid, lengthof(ea3.softid), options.softid);
}
if (options.pcbid != NULL) {
str_cpy(ea3.pcbid, lengthof(ea3.pcbid), options.pcbid);
}
if (!ea3.hardid[0]) {
ea3_ident_hardid_from_ethernet(&ea3);
}
/* Invoke dll_entry_init */
app_config = boot_property_load(options.app_config_path);
app_config_root = property_search(app_config, 0, "/param");
if (app_config_root == NULL) {
log_fatal("%s: /param missing", options.app_config_path);
}
if (IsDebuggerPresent()) {
/* Opportunity for breakpoint setup etc */
DebugBreak();
}
ok = ea3_ident_invoke_module_init(&ea3, &module, app_config_root);
if (!ok) {
log_fatal("%s: dll_module_init() returned failure", options.module);
}
boot_property_free(app_config);
ea3_ident_to_property(&ea3, ea3_config);
/* Start up e-Amusement client */
ea3_boot(ea3_config_root);
boot_property_free(ea3_config);
/* Run application */
module_context_invoke_main(&module);
/* Shut down */
ea3_shutdown();
log_to_writer(log_writer_file, stdout);
avs_context_fini();
if (logfile != INVALID_HANDLE_VALUE) {
CloseHandle(logfile);
}
module_context_fini(&module);
options_fini(&options);
return EXIT_SUCCESS;
}
+82
View File
@@ -0,0 +1,82 @@
#include <windows.h>
#include "imports/avs.h"
#include "imports/eapki.h"
#include "launcher/module.h"
#include "util/log.h"
#include "util/str.h"
void module_context_init(struct module_context *module, const char *path)
{
log_assert(module != NULL);
log_assert(path != NULL);
module->dll = LoadLibrary(path);
if (module->dll == NULL) {
LPSTR buffer;
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR) &buffer, 0, NULL);
log_fatal("%s: Failed to load game DLL: %s", path, buffer);
LocalFree(buffer);
}
module->path = str_dup(path);
}
bool module_context_invoke_init(const struct module_context *module,
char *sidcode, struct property_node *app_config)
{
dll_entry_init_t init;
log_assert(module != NULL);
log_assert(sidcode != NULL);
log_assert(app_config != NULL);
init = (void *) GetProcAddress(module->dll, "dll_entry_init");
if (init == NULL) {
log_fatal(
"%s: dll_entry_init not found. Is this a game DLL?",
module->path);
}
return init(sidcode, app_config);
}
bool module_context_invoke_main(const struct module_context *module)
{
/* GCC warns if you call a variable "main" */
dll_entry_main_t main_;
log_assert(module != NULL);
main_ = (void *) GetProcAddress(module->dll, "dll_entry_main");
if (main_ == NULL) {
log_fatal(
"%s: dll_entry_main not found. Is this a game DLL?",
module->path);
}
return main_();
}
void module_context_fini(struct module_context *module)
{
if (module == NULL) {
return;
}
free(module->path);
if (module->dll != NULL) {
FreeLibrary(module->dll);
}
}
+19
View File
@@ -0,0 +1,19 @@
#ifndef LAUNCHER_MODULE_H
#define LAUNCHER_MODULE_H
#include <windows.h>
#include "imports/avs.h"
struct module_context {
HMODULE dll;
char *path;
};
void module_context_init(struct module_context *module, const char *path);
bool module_context_invoke_init(const struct module_context *module,
char *sidcode, struct property_node *app_config);
bool module_context_invoke_main(const struct module_context *module);
void module_context_fini(struct module_context *module);
#endif
+173
View File
@@ -0,0 +1,173 @@
#include <stdio.h>
#include <stdlib.h>
#include "imports/avs.h"
#include "launcher/options.h"
#include "util/array.h"
#include "util/str.h"
#define DEFAULT_HEAP_SIZE 16777216
void options_init(struct options *options)
{
options->std_heap_size = DEFAULT_HEAP_SIZE;
options->avs_heap_size = DEFAULT_HEAP_SIZE;
options->app_config_path = "prop/app-config.xml";
options->avs_config_path = "prop/avs-config.xml";
options->ea3_config_path = "prop/ea3-config.xml";
options->softid = NULL;
options->pcbid = NULL;
options->module = NULL;
options->logfile = NULL;
options->remote_debugger = false;
array_init(&options->hook_dlls);
}
bool options_read_cmdline(struct options *options, int argc, const char **argv)
{
for (int i = 1 ; i < argc ; i++) {
if (argv[i][0] == '-') {
switch (argv[i][1]) {
case 'A':
if (i + 1 >= argc) {
return false;
}
options->app_config_path = argv[++i];
break;
case 'E':
if (i + 1 >= argc) {
return false;
}
options->ea3_config_path = argv[++i];
break;
case 'V':
if (i + 1 >= argc) {
return false;
}
options->avs_config_path = argv[++i];
break;
case 'P':
if (i + 1 >= argc) {
return false;
}
options->pcbid = argv[++i];
break;
case 'R':
if (i + 1 >= argc) {
return false;
}
options->softid = argv[++i];
break;
case 'H':
if (i + 1 >= argc) {
return false;
}
options->avs_heap_size = (size_t)strtol(argv[++i],NULL,0);
if (options->avs_heap_size == 0) {
return false;
}
break;
#ifdef AVS_HAS_STD_HEAP
case 'T':
if (i + 1 >= argc) {
return false;
}
options->std_heap_size = (size_t)strtol(argv[++i],NULL,0);
if (options->std_heap_size == 0) {
return false;
}
break;
#endif
case 'K':
if (i + 1 >= argc) {
return false;
}
*array_append(const char *,&options->hook_dlls)=argv[++i];
break;
case 'Y':
if (i + 1 >= argc) {
return false;
}
options->logfile = argv[++i];
break;
case 'D':
options->remote_debugger = true;
break;
default:
break;
}
} else {
if (!options->module) {
options->module = argv[i];
}
}
}
if (options->module) {
return true;
} else {
return false;
}
}
void options_print_usage(void)
{
fprintf(stderr,
"Usage: launcher.exe [launcher options...] <app.dll> [hooks options...] \n"
"\n"
" The following options can be specified before the app DLL path:\n"
"\n"
" -A [filename] App configuration file (default: prop/app-config.xml)\n"
" -V [filename] AVS configuration file (default: prop/avs-config.xml)\n"
" -E [filename] ea3 configuration file (default: prop/ea3-config.xml)\n"
" -H [bytes] AVS heap size (default: 16777216)\n"
#ifdef AVS_HAS_STD_HEAP
" -T [bytes] 'std' heap size (default 16777216)\n"
#endif
" -P [pcbid] Specify PCBID (default: use ea3 config)\n"
" -R [pcbid] Specify Soft ID (default: use ea3 config)\n"
" -K [filename] Load hook DLL (can be specified multiple times)\n"
" -Y [filename] Log to a file in addition to the console\n"
" -D Halt the launcher before bootstrapping AVS until a"
" remote debugger is attached\n"
);
}
void options_fini(struct options *options)
{
array_fini(&options->hook_dlls);
}
+28
View File
@@ -0,0 +1,28 @@
#ifndef LAUNCHER_OPTIONS_H
#define LAUNCHER_OPTIONS_H
#include <stdbool.h>
#include <stddef.h>
#include "util/array.h"
struct options {
size_t std_heap_size;
size_t avs_heap_size;
const char *app_config_path;
const char *avs_config_path;
const char *ea3_config_path;
const char *softid;
const char *pcbid;
const char *module;
const char *logfile;
struct array hook_dlls;
bool remote_debugger;
};
void options_init(struct options *options);
bool options_read_cmdline(struct options *options, int argc, const char **argv);
void options_print_usage(void);
void options_fini(struct options *options);
#endif
+79
View File
@@ -0,0 +1,79 @@
#include <windows.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include "imports/avs.h"
#include "launcher/property.h"
#include "util/log.h"
#include "util/mem.h"
static int boot_property_fread(uint32_t context, void *bytes, size_t nbytes)
{
FILE *f;
f = TlsGetValue(context);
return fread(bytes, 1, nbytes, f);
}
struct property *boot_property_load(const char *filename)
{
struct property *prop;
void *buffer;
int nbytes;
FILE *f;
uint32_t f_keyhole;
/* AVS callbacks are only given a 32-bit context parameter, even in 64-bit
builds of AVS. We allocate a 32-bit TLS key and pass the context in this
manner instead. Inefficient, but it works. */
f = fopen(filename, "r");
f_keyhole = TlsAlloc();
TlsSetValue(f_keyhole, f);
if (f == NULL) {
log_fatal("%s: Error opening configuration file", filename);
}
nbytes = property_read_query_memsize(boot_property_fread, f_keyhole, 0, 0);
if (nbytes < 0) {
log_fatal("%s: Error parsing configuration file", filename);
}
buffer = xmalloc(nbytes);
prop = property_create(
PROPERTY_FLAG_READ |
PROPERTY_FLAG_WRITE |
PROPERTY_FLAG_CREATE |
PROPERTY_FLAG_APPEND,
buffer,
nbytes);
rewind(f);
if (!property_insert_read(prop, 0, boot_property_fread, f_keyhole)) {
log_fatal("%s: Error parsing configuration file", filename);
}
TlsFree(f_keyhole);
fclose(f);
return prop;
}
void boot_property_free(struct property *prop)
{
void *buffer;
buffer = property_desc_to_buffer(prop);
property_destroy(prop);
free(buffer);
}
+9
View File
@@ -0,0 +1,9 @@
#ifndef LAUNCHER_PROPERTY_H
#define LAUNCHER_PROPERTY_H
#include "imports/avs.h"
struct property *boot_property_load(const char *filename);
void boot_property_free(struct property *prop);
#endif
+167
View File
@@ -0,0 +1,167 @@
#include <windows.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <wchar.h>
#include "hook/table.h"
#include "launcher/stubs.h"
#include "util/defs.h"
#include "util/log.h"
struct ikey_status {
uint32_t field_0;
uint8_t field_4;
uint8_t field_5;
uint8_t field_6;
uint8_t field_7;
uint32_t cert_valid_start;
uint32_t cert_valid_end;
};
struct stub {
const char *name;
void *proc;
};
typedef void (*bt_get_fucked_t)(uint32_t /* even in 64-bit */ context);
static HMODULE STDCALL my_GetModuleHandleA(const char *name);
static HMODULE STDCALL my_GetModuleHandleW(const wchar_t *name);
static void * STDCALL my_GetProcAddress(HMODULE dll, const char *name);
static void bt_get_ikey_status(struct ikey_status *ik);
#if AVS_VERSION >= 1600
static void bt_get_fucked(bt_get_fucked_t callback, uint32_t ctx);
#endif
static void bt_fcheck_init(void);
static void *bt_fcheck_main(void *unknown);
static void bt_fcheck_finish(void);
static HMODULE (STDCALL *real_GetModuleHandleA)(const char *name);
static HMODULE (STDCALL *real_GetModuleHandleW)(const wchar_t *name);
static void * (STDCALL *real_GetProcAddress)(HMODULE dll, const char *name);
static struct stub stub_list[] = {
#if AVS_VERSION >= 1600
{ "k_bt0001", bt_get_ikey_status },
{ "k_bt0002", bt_get_fucked },
#else
{ "bt_get_ikey_status", bt_get_ikey_status },
#endif
{ "bt_fcheck_init", bt_fcheck_init },
{ "bt_fcheck_main", bt_fcheck_main },
{ "bt_fcheck_finish", bt_fcheck_finish },
};
static struct hook_symbol stub_hook_syms[] = {
{
.name = "GetModuleHandleA",
.patch = my_GetModuleHandleA,
.link = (void *)&real_GetModuleHandleA
},
{
.name = "GetModuleHandleW",
.patch = my_GetModuleHandleW,
.link = (void *)&real_GetModuleHandleW
},
{
.name = "GetProcAddress",
.patch = my_GetProcAddress,
.link = (void *)&real_GetProcAddress
},
};
static HMODULE STDCALL my_GetModuleHandleA(const char *name)
{
/* Check name for null because winio32 calls this with null parameters
when the module is loaded on win xp (doesn't happen on win 7) */
if ( name != NULL &&
(_stricmp(name, "kbt.dll") == 0 ||
_stricmp(name, "kld.dll") == 0)) {
name = NULL;
}
return real_GetModuleHandleA(name);
}
static HMODULE STDCALL my_GetModuleHandleW(const wchar_t *name)
{
/* Check name for null because winio32 calls this with null parameters
when the module is loaded on win xp (doesn't happen on win 7) */
if ( name != NULL &&
(wcsicmp(name, L"kbt.dll") == 0 ||
wcsicmp(name, L"kld.dll") == 0)) {
name = NULL;
}
return real_GetModuleHandleW(name);
}
static void * STDCALL my_GetProcAddress(HMODULE dll, const char *name)
{
size_t i;
if (dll != real_GetModuleHandleA(NULL)) {
return real_GetProcAddress(dll, name);
}
for (i = 0 ; i < lengthof(stub_list) ; i++) {
if (strcmp(stub_list[i].name, name) == 0) {
return stub_list[i].proc;
}
}
log_warning("Request for unknown stub %s", name);
return NULL;
}
void stubs_init(void)
{
hook_table_apply(
NULL,
"kernel32.dll",
stub_hook_syms,
lengthof(stub_hook_syms));
}
static void bt_get_ikey_status(struct ikey_status *ik)
{
memset(ik, 0, sizeof(*ik) * 2);
ik[0].field_4 = true;
ik[0].field_6 = true;
ik[1].field_4 = true;
ik[1].field_6 = true;
/* Not strictly necessary */
ik[0].cert_valid_end = -1;
ik[1].cert_valid_end = -1;
}
#if AVS_VERSION >= 1600
static void bt_get_fucked(bt_get_fucked_t callback, uint32_t ctx)
{
log_info(">>> k_bt0002");
callback(ctx);
log_info("<<< k_bt0002");
}
#endif
static void bt_fcheck_init(void)
{}
static void *bt_fcheck_main(void *unknown)
{
return 0;
}
static void bt_fcheck_finish(void)
{}
+6
View File
@@ -0,0 +1,6 @@
#ifndef LAUNCHER_STUBS_H
#define LAUNCHER_STUBS_H
void stubs_init(void);
#endif