Skip to content

Commit

Permalink
Initial commit.
Browse files Browse the repository at this point in the history
  • Loading branch information
dkeetonx committed Jun 17, 2020
0 parents commit 4fe9b88
Show file tree
Hide file tree
Showing 8 changed files with 270 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
config.mk

*.o

*.dll
!cncnet5.dll
23 changes: 23 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
-include config.mk

OUTPUT = rename.dll
CFLAGS = -std=c99 -Iinc/
DLL_LDFLAGS = -mdll -Wl,--enable-stdcall-fixup

OBJS = src/rename.o src/ares.o

CC ?= gcc
STRIP ?= strip
RM ?= rm

.PHONY: default
default: $(OUTPUT)

.PHONY: all
all: rename.dll

$(OUTPUT): $(OBJS)
$(CC) $(CFLAGS) $(DLL_LDFLAGS) -o $@ $^ -lmsvcrt
$(STRIP) $@
clean:
$(RM) $(OUTPUT) $(OBJS)
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
CnCNet for Ares
================================================================================

Spawns Yuri's Revenge and connects players through cncnet5. This project should be used in conjunction with the [xna-cncnet-client](https://github.com/CnCNet/xna-cncnet-client) and [Ares](https://launchpad.net/ares/+download)

### Usage
- Place cncnet5.dll in you mod folder with the xna-cncncet-client and the Ares files.
- Optionally place rename.dll in the mod directory.
- Syringe from Ares will automatically detect and include cncnet5.dll.
- Configure xna-cncnet-client to execute Syringe.exe rather than game(md).exe

### Building
- Download cncnet-for-ares
- Edit src/rename.c, change the strings for the Gane name and file locations. Do not exceed the size of the existing strings in the game.
- Download [win-builds](https://downloads.cncnet.org/win-builds-for-patching.zip) and install it by double clicking win-install.bat
- In the cncnet5-for-ares run build.cmd by double clicking on it. Read the output window any errors you may introduced.
- You should now have rename.dll. Now you can rename rename.dll to something appropriate for your mod (the name will not stop it from being loaded by Syringe).


### Caveats
- Source code for cncnet5.dll is not public, only the cncnet5.dll file is provided here.
- You do not need to use the command line -SPAWN argument.
- You may need to edit build.cmd if win-builds did not get installed into C:\win-builds-patch-32\
9 changes: 9 additions & 0 deletions build.cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
@echo off
REM
REM cnc-patch environment config
REM
set PATH=C:\win-builds-patch-32\bin
gmake clean
pause
gmake all
pause
Binary file added cncnet5.dll
Binary file not shown.
61 changes: 61 additions & 0 deletions inc/patch.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright (c) 2013, 2014, 2020 Toni Spets <[email protected]>
* Daniel Keeton Jr <[email protected]>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#define CLEAR(start, value, end) \
__asm ( \
".section .patch,\"d0\";" \
".long " #start ";" \
".long " #end "-" #start ";" \
".fill " #end "-" #start ", 1, " #value ";" \
)

#define LJMP(src, dst) \
__asm ( \
".section .patch,\"d0\";" \
".long " #src ";" \
".long 5;" \
".byte 0xE9;" \
".long " #dst "-" #src " - 5;" \
)

#define CALL(src, dst) \
__asm ( \
".section .patch,\"d0\";" \
".long " #src ";" \
".long 5;" \
".byte 0xE8;" \
".long " #dst "-" #src " - 5;" \
)

#define SETDWORD(dst, value) \
__asm ( \
".section .patch,\"d0\";" \
".long " #dst ";" \
".long 4;" \
".long " #value ";" \
)

#define SETSTRING(dst, value) \
__asm ( \
".section .patch,\"d0\";" \
".long " #dst ";" \
".long (_memcpy_end_" #dst \
" - _memcpy_start_" #dst ");" \
"_memcpy_start_" #dst ":;" \
".asciz " #value ";" \
"_memcpy_end_" #dst ":;" \
)
94 changes: 94 additions & 0 deletions src/ares.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* Copyright (c) 2013, 2014 Toni Spets <[email protected]>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#include <windows.h>
#include <stdio.h>

// this tricks syringe to load this dll
__asm (
".section .syhks00,\"d8\";" // AlexB said the alignment has to be 16 bytes
".long 0;"
".long 0;"
".string \"stub\";"
);

#ifdef WWDEBUG
#define dprintf printf
#else
#define dprintf(fmt, ...)
#endif

static DWORD get_dword(char **p)
{
DWORD ret = *(DWORD *)*p;
*p += sizeof(DWORD);
return ret;
}

BOOL WINAPI __declspec(dllexport)
DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
if (fdwReason == DLL_PROCESS_ATTACH)
{
char buf[MAX_PATH + 1] = { 0 };
GetModuleFileName(NULL, buf, sizeof buf);

dprintf("Patching CnCNet 5 to %s\n", buf);

PIMAGE_DOS_HEADER dos_hdr = (void *)hinstDLL;
PIMAGE_NT_HEADERS nt_hdr = (void *)((char *)hinstDLL + dos_hdr->e_lfanew);

char *patch = NULL;
int patch_len = 0;

for (int i = 0; i < nt_hdr->FileHeader.NumberOfSections; i++)
{
PIMAGE_SECTION_HEADER sct_hdr = IMAGE_FIRST_SECTION(nt_hdr) + i;

if (strcmp(".patch", (char *)sct_hdr->Name) == 0)
{
patch = (char *)((char *)hinstDLL + sct_hdr->VirtualAddress);
patch_len = sct_hdr->Misc.VirtualSize;
break;
}

sct_hdr++;
}

dprintf("Found .patch @ %p (%d bytes)\n", patch, patch_len);

if (patch)
{
for (char *p = patch; p < patch + patch_len;)
{
DWORD paddress = get_dword(&p);
if (paddress == 0) break;

DWORD plength = get_dword(&p);

dprintf("PATCH %8u bytes -> %8X\n", (unsigned int)plength, (unsigned int)paddress);
DWORD protect = 0;
VirtualProtect((void *)paddress, plength, PAGE_EXECUTE_READWRITE, &protect);
memcpy((void *)paddress, p, plength);
VirtualProtect((void *)paddress, plength, protect, NULL);

p += plength;
}
}
}

return TRUE;
}
54 changes: 54 additions & 0 deletions src/rename.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright (c) 2020 Daniel Keeton Jr <[email protected]>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#include "patch.h"

/*
* Change the following strings
* Do not make your new strings longer than the original strings.
* Use the line of ); as a guide, if they aren't all lined up
* then your new string isn't the correct length.
*/

SETSTRING( 0x00849F48, "Yuri's Revenge" );
SETSTRING( 0x0082668C, "EXPANDMD%02d.MIX" );
SETSTRING( 0x0082621C, "AIMD.INI" );
SETSTRING( 0x00826254, "ARTMD.INI" );
SETSTRING( 0x00826198, "BATTLEMD.INI" );
SETSTRING( 0x008261A8, "BATTLEMD*.INI" );
SETSTRING( 0x008295E8, "%sMD.INI" );
SETSTRING( 0x00825DF0, "EVAMD.INI" );
SETSTRING( 0x00830370, "MAPSELMD.INI" );
SETSTRING( 0x00839724, "MISSIONMD.INI" );
SETSTRING( 0x00826260, "RULESMD.INI" );
SETSTRING( 0x0082626C, "RULEMD*.INI" );
SETSTRING( 0x00825E50, "SOUNDMD.INI" );
SETSTRING( 0x0081C24C, "THEMEMD.MIX" );
SETSTRING( 0x00825D94, "THEMEMD.INI" );
SETSTRING( 0x00826444, "RA2MD.INI" );
SETSTRING( 0x00826614, "ELOCAL*.MIX" );
SETSTRING( 0x00826620, "ECACHE*.MIX" );
SETSTRING( 0x0081C284, "MULTIMD.MIX" );
SETSTRING( 0x00826780, "MULTIMD.MIX" );
SETSTRING( 0x0081C2EC, "MAPSMD%02d.MIX" );
SETSTRING( 0x0082679C, "MAPSMD*.MIX" );
SETSTRING( 0x0081C210, "MOVMD%02d.MIX" );
SETSTRING( 0x008266A0, "MIXFILES\\MOVMD03.MIX" );
SETSTRING( 0x008266B8, "MOVMD03.MIX" );
SETSTRING( 0x008266C4, "MIXFILES\\MOVMD*.MIX" );
SETSTRING( 0x008266D8, "MIXFILES\\MOVMD01.MIX" );
SETSTRING( 0x008266F0, "MOVMD01.MIX" );
SETSTRING( 0x00826748, "MOVMD*.MIX" );

0 comments on commit 4fe9b88

Please sign in to comment.