Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
delthas committed Jun 8, 2019
0 parents commit 26578c4
Show file tree
Hide file tree
Showing 20 changed files with 1,759 additions and 0 deletions.
61 changes: 61 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
BasedOnStyle: LLVM
AccessModifierOffset: -2
AlignAfterOpenBracket: DontAlign
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: DontAlign
AlignOperands: false
AlignTrailingComments: false
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Empty
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: No
BinPackArguments: true
BinPackParameters: true
BreakBeforeBinaryOperators: All
BreakBeforeBraces: Attach
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: AfterColon
BreakInheritanceList: AfterColon
BreakStringLiterals: true
ColumnLimit: 160
CompactNamespaces: true
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 2
ContinuationIndentWidth: 2
Cpp11BracedListStyle: true
FixNamespaceComments: true
IncludeBlocks: Regroup
IndentCaseLabels: false
IndentPPDirectives: None
IndentWidth: 2
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: false
Language: Cpp
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
PointerAlignment: Right
ReflowComments: true
SortIncludes: false
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: false
SpaceBeforeInheritanceColon: false
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
TabWidth: 2
UseTab: Always
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
*.exe
*.dll
.vs
.idea
cmake-*
CMakeSettings.json*
/autopunch-loader/dll*.go
/autopunch-loader/address.go
*.syso
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "detours"]
path = detours
url = https://github.com/microsoft/Detours.git
43 changes: 43 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
cmake_minimum_required(VERSION 3.12)
project(autopunch C CXX)

set(CMAKE_C_STANDARD 11)

# /W4 /WX /Zi /MT /Gy /Gm- /Zl /Od

# DETOURS_TARGET_PROCESSOR=X64
# DETOURS_OPTION_PROCESSOR=X86
# DETOURS_OPTION_BITS=32

add_library(autopunch MODULE
detours/src/detours.cpp
detours/src/modules.cpp
detours/src/disasm.cpp
detours/src/image.cpp
detours/src/creatwth.cpp
detours/src/disolx86.cpp
detours/src/disolx64.cpp
detours/src/disolia64.cpp
detours/src/disolarm.cpp
detours/src/disolarm64.cpp
inject.c)
target_include_directories(autopunch PRIVATE detours/src)
target_link_libraries(autopunch PRIVATE ws2_32)
target_compile_definitions(autopunch PRIVATE -DWIN32_LEAN_AND_MEAN -D_CRT_SECURE_NO_WARNINGS)
target_compile_options(autopunch PRIVATE
"$<$<CONFIG:DEBUG>:/MTd>"
"$<$<NOT:$<CONFIG:DEBUG>>:/MT>")

if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(TARGET_FILE_BITS 64)
else()
set(TARGET_FILE_BITS 86)
endif()
if(CMAKE_BUILD_TYPE STREQUAL Debug)
set(TARGET_FILE_BUILD dbg)
else()
set(TARGET_FILE_BUILD rel)
endif()

add_custom_target(autopunch_copy DEPENDS autopunch COMMAND_EXPAND_LISTS VERBATIM
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:autopunch> ${CMAKE_SOURCE_DIR}/../autopunch-loader/autopunch.x${TARGET_FILE_BITS}.${TARGET_FILE_BUILD}.dll)
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2019 delthas

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
60 changes: 60 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# autopunch ![](https://img.shields.io/github/downloads/delthas/autopunch/total.svg?style=flat-square)

**This program lets you host & connect to friends to play peer-to-peer games without having to open or redirect any port. This does not add any latency to the connection compared to redirecting ports manually.**

**You can play with users that don't use autopunch without compability issues and can always leave it enabled. However, the tool will only do its magic if both peers use autopunch.**

*Technical details: autopunch injects itself into a process and detours some winsock calls (sendto, recvfrom, ...) to rewrite addresses so that they appear to be internal ports rather than external ports. It additionally performs hole punching by using a STUN-like relay which helps know internal ports of other users.*

## How to use

- **Download the [latest version for Windows 64 bits](https://github.com/delthas/autopunch/releases/latest/download/autopunch.win64.exe) (use this link, not any other download button)**
- **Start your peer-to-peer game** *(for Touhou Hisoutensoku players: also run SokuRoll now, if needed)*
- **Double-click the downloaded executable file to run it**; there is no setup or anything so put the file somewhere you'll remember (doesn't have to be in the game folder)
- If a Windows Defender SmartScreen popup appears, click on "More information", then click on "Run anyway"
- If a Windows Firewall popup appears, check the "Private networks" and "Public networks" checkboxes, then click on "Allow access"
- If prompted for an update, just wait, everything will be updated and restart automatically
- **Click on the game you wish to play in the list, then click "Punch!"**; the window will close and "autopunch" will appear in the game window title *(just like SokuRoll)*
- **Play!** Host on any port, or connect to the IP and port the host gives you just as usual.
- You can host and connect to peer with or without using autopunch: no compatibility issues, you can always leave it running.
- **However, if a host didn't forward its ports, both peers will need autopunch, not just the one hosting!**

![](doc/screen.jpg)

### Troubleshooting

- If you experience any issue when using autopunch, make sure that both peers are running autopunch. *For Hisoutensoku players: if using SokuRoll, run it before running the tool.*
- For some very rare users having a very old or cheap Internet router, or playing at a work office, autopunch might just not work *when they are hosting*. Try switching who hosts if this happens.
- If you have any other issue or feedback, either contact me on Discord at `cc#6439` or [open an issue on Github](https://github.com/delthas/autopunch/issues/new). **When doing that, please check the Debug checkbox, punch and play again, close the game and send me the log file.**

## Advanced usage

- No command-line flags, no advanced usage. If you need anything specific open an issue or ask me.

## Building

Quick overview of the components of the project:
- `inject.c`: the core autopunch DLL, that is injected into a game; has both 32 and 64 bit versions, release and debug versions;
- `address`: a tiny program to get the address of the `LoadLibraryW` function of the WoW `Kernel32` module; this works because ASLR is only done once per reboot;
- `packer`: a tiny program to pack a binary file as a string in a Go source file so that it can be included in an executable;
- `relay`: the STUN-like relay used by autopunch;
- `loader`: the program that has the GUI and autoupdates, and starts the injection of the autopunch DLL; the final executable packs the 4 autopunch DLLs, the address executable, and a Win32 app manifest.

**Do not use `go get`. Clone manually.**

Preparation:
- make sure you pulled all submodules;
- install an `i686-w64-mingw32-gcc` toolchain (for example with MSYS2);
- install the Microsoft Visual C++ Build Tools;
- install CMake;
- install Go;
- install https://github.com/akavel/rsrc (and add $GOPATH/bin to PATH if needed).

Build order:
- build `address` with CMake, compiling with `i686-w64-mingw32-gcc`, profile MinSizeRel;
- build `packer` with Go; `go install` it / add it to your PATH;
- build `inject.c` (at the root) with CMake four times: Debug and Release, for Visual C++ Build Tools x86 and x64; use the `autopunch_copy` target to put the DLLs in the right folder for next steps;
- generate `loader` with: `go generate loader.go`;
- build `loader`, targeting GOOS=windows GOARCH=amd64, with: `go build -ldflags="-H windowsgui -s -w -X main.version=<version>" -tags walk_use_cgo`; `version` is e.g. `v0.0.1`.

Building the relay (Go) is straightforward.
12 changes: 12 additions & 0 deletions autopunch-address/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
cmake_minimum_required(VERSION 3.12)
project(autopunch C CXX)

set(CMAKE_C_STANDARD 11)

# compile with i386 mingw
add_executable(address address.c)
target_compile_definitions(address PRIVATE -DWIN32_LEAN_AND_MEAN)
target_link_options(address PRIVATE -mwindows $<$<CONFIG:RELEASE>:-s> $<$<CONFIG:MINSIZEREL>:-s>)

add_custom_target(address_copy DEPENDS address COMMAND_EXPAND_LISTS VERBATIM
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:address> "${CMAKE_SOURCE_DIR}/address.exe")
13 changes: 13 additions & 0 deletions autopunch-address/address.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include <windows.h>

int main(int argc, char **argv) {
if(argc != 3) {
return 0;
}
HMODULE module = LoadLibraryA(argv[1]);
if(!module) {
return 0;
}
FARPROC proc = GetProcAddress(module, argv[2]);
return (int)proc;
}
14 changes: 14 additions & 0 deletions autopunch-loader/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module github.com/delthas/autopunch/autopunch-loader

go 1.12

require (
github.com/akutz/sortfold v0.2.1
github.com/lxn/walk v0.0.0-20190605135739-7223200e844a
github.com/lxn/win v0.0.0-20190529120726-270e6e4be94d // indirect
github.com/machinebox/progress v0.2.0
github.com/matryer/is v1.2.0 // indirect
golang.org/x/sys v0.0.0-20190608050228-5b15430b70e3
golang.org/x/text v0.3.2 // indirect
gopkg.in/Knetic/govaluate.v3 v3.0.0 // indirect
)
17 changes: 17 additions & 0 deletions autopunch-loader/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
github.com/akutz/sortfold v0.2.1 h1:u9x3FC6oM+6gZKEVNRnmVafJgappwrv9YqpELQCYViI=
github.com/akutz/sortfold v0.2.1/go.mod h1:m1NArmessx+/3z2N8MiiTjq79A3WwZwDDiZ7eeD4jHA=
github.com/lxn/walk v0.0.0-20190605135739-7223200e844a h1:CtnHTpYxiq8reYXJtZd1eUor+NEN29ZLHHT3z3nFams=
github.com/lxn/walk v0.0.0-20190605135739-7223200e844a/go.mod h1:E23UucZGqpuUANJooIbHWCufXvOcT6E7Stq81gU+CSQ=
github.com/lxn/win v0.0.0-20190529120726-270e6e4be94d h1:SJyuddpDtiXMTcJmzC0OuphQdSZCabKW4iQWSE9FFR4=
github.com/lxn/win v0.0.0-20190529120726-270e6e4be94d/go.mod h1:oO6+4g3P1GcPAG7LPffwn8Ye0cxW0goh0sUZ6+lRFPs=
github.com/machinebox/progress v0.2.0 h1:7z8+w32Gy1v8S6VvDoOPPBah3nLqdKjr3GUly18P8Qo=
github.com/machinebox/progress v0.2.0/go.mod h1:hl4FywxSjfmkmCrersGhmJH7KwuKl+Ueq9BXkOny+iE=
github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A=
github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA=
golang.org/x/sys v0.0.0-20190608050228-5b15430b70e3 h1:xUZPeCzQtkdgRi9RjXIA+3w3RdyDLPqiaJlza5Fqpog=
golang.org/x/sys v0.0.0-20190608050228-5b15430b70e3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/Knetic/govaluate.v3 v3.0.0 h1:18mUyIt4ZlRlFZAAfVetz4/rzlJs9yhN+U02F4u1AOc=
gopkg.in/Knetic/govaluate.v3 v3.0.0/go.mod h1:csKLBORsPbafmSCGTEh3U7Ozmsuq8ZSIlKk1bcqph0E=
13 changes: 13 additions & 0 deletions autopunch-loader/loader.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include "loader.h"

BOOL cEnumWindowCallbackList(HWND handle, LPARAM data) {
void enumWindowCallbackList(void *handle, void *data);
enumWindowCallbackList((void*)handle, (void*)data);
return TRUE;
}

BOOL cEnumWindowCallbackSetName(HWND handle, LPARAM data) {
void enumWindowCallbackSetName(void *handle, void *data);
enumWindowCallbackSetName((void*)handle, (void*)data);
return TRUE;
}
Loading

0 comments on commit 26578c4

Please sign in to comment.