Skip to content

Commit

Permalink
Port to Windows, and attempt adding an action.
Browse files Browse the repository at this point in the history
  • Loading branch information
Dadoum committed Jun 12, 2023
1 parent 7d77bbc commit 6d3cc85
Show file tree
Hide file tree
Showing 9 changed files with 172 additions and 49 deletions.
32 changes: 32 additions & 0 deletions .github/workflows/cmake-windows.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: x86_64 builds

on: push

env:
BUILD_TYPE: Release

jobs:
build-anisette-server-windows-x86_64:
runs-on: windows-2019

steps:
- uses: actions/checkout@v3
with:
submodules: recursive

- uses: actions/checkout@v2
- uses: dlang-community/setup-dlang@v1
with:
compiler: ldc-latest

- name: Build
run: dub build :anisette-server -b release -c "static"

- name: Rename
run: mv "${{github.workspace}}/bin/provision_anisette-server.exe" "${{github.workspace}}/bin/anisette-server-x86_64.exe"

- uses: actions/upload-artifact@v3
with:
name: anisette-server-x86_64
path: |
${{github.workspace}}/bin/anisette-server-x86_64.exe
7 changes: 6 additions & 1 deletion anisette_server/app.d
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,12 @@ void main(string[] args) {
import std.datetime.systime;
import std.datetime.timezone;
import core.time;
auto time = Clock.currTime();
version (Windows) {
import std.datetime.timezone;
auto time = Clock.currTime(UTC());
} else {
auto time = Clock.currTime();
}

auto otp = adi.requestOTP(dsId);

Expand Down
22 changes: 11 additions & 11 deletions lib/provision/adi.d
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public class ADI {

public void provisioningPath(string path) {
__provisioningPath = path;
pADISetProvisioningPath.androidInvoke(path.toStringz).unwrapADIError();
androidInvoke!pADISetProvisioningPath(path.toStringz).unwrapADIError();
}

private string __identifier;
Expand All @@ -68,7 +68,7 @@ public class ADI {

public void identifier(string identifier) {
__identifier = identifier;
pADISetAndroidID.androidInvoke(identifier.ptr, cast(uint) identifier.length).unwrapADIError();
androidInvoke!pADISetAndroidID(identifier.ptr, cast(uint) identifier.length).unwrapADIError();
}

public this(string libraryPath) {
Expand Down Expand Up @@ -121,11 +121,11 @@ public class ADI {
}

public void loadLibrary(string libraryPath) {
pADILoadLibraryWithPath.androidInvoke(cast(const(char*)) libraryPath.toStringz).unwrapADIError();
androidInvoke!pADILoadLibraryWithPath(cast(const(char*)) libraryPath.toStringz).unwrapADIError();
}

public void eraseProvisioning(ulong dsId) {
pADIProvisioningErase.androidInvoke(dsId).unwrapADIError();
androidInvoke!pADIProvisioningErase(dsId).unwrapADIError();
}

struct SynchronizationResumeMetadata {
Expand Down Expand Up @@ -154,7 +154,7 @@ public class ADI {
ubyte* mid;
uint midLength;

pADISynchronize.androidInvoke(
androidInvoke!pADISynchronize(
dsId,
serverIntermediateMetadata.ptr,
cast(uint) serverIntermediateMetadata.length,
Expand All @@ -168,11 +168,11 @@ public class ADI {
}

public void destroyProvisioning(uint session) {
pADIProvisioningDestroy.androidInvoke(session).unwrapADIError();
androidInvoke!pADIProvisioningDestroy(session).unwrapADIError();
}

public void endProvisioning(uint session, ubyte[] persistentTokenMetadata, ubyte[] trustKey) {
pADIProvisioningEnd.androidInvoke(
androidInvoke!pADIProvisioningEnd(
session,
persistentTokenMetadata.ptr,
cast(uint) persistentTokenMetadata.length,
Expand Down Expand Up @@ -205,7 +205,7 @@ public class ADI {
uint cpimLength;
uint session;

pADIProvisioningStart.androidInvoke(
androidInvoke!pADIProvisioningStart(
dsId,
serverProvisioningIntermediateMetadata.ptr,
cast(uint) serverProvisioningIntermediateMetadata.length,
Expand All @@ -218,7 +218,7 @@ public class ADI {
}

public bool isMachineProvisioned(ulong dsId) {
int errorCode = pADIGetLoginCode.androidInvoke(dsId);
int errorCode = androidInvoke!pADIGetLoginCode(dsId);

if (errorCode == 0) {
return true;
Expand All @@ -230,7 +230,7 @@ public class ADI {
}

public void dispose(void* ptr) {
pADIDispose.androidInvoke(ptr).unwrapADIError();
androidInvoke!pADIDispose(ptr).unwrapADIError();
}

struct OneTimePassword {
Expand Down Expand Up @@ -259,7 +259,7 @@ public class ADI {
ubyte* mid;
uint midLength;

pADIOTPRequest.androidInvoke(
androidInvoke!pADIOTPRequest(
dsId,
&mid,
&midLength,
Expand Down
55 changes: 50 additions & 5 deletions lib/provision/androidlibrary.d
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ public class AndroidLibrary {
package SymbolHashTable hashTable;
package AndroidLibrary[] loadedLibraries;

void[][] stubMaps;
size_t currentMapOffset = 0;
void[][] segments;

public void*[string] hooks;

private ElfW!"Shdr"[] relocationSections;
Expand Down Expand Up @@ -179,7 +183,7 @@ public class AndroidLibrary {
addend = *cast(size_t*) (cast(size_t) allocation.ptr + offset);
}
}
auto symbol = getSymbolImplementation(getSymbolName(dynamicSymbolTable[symbolIndex]));
auto symbol = getSymbolImplementation(&dynamicStringTable[dynamicSymbolTable[symbolIndex].st_name]);

auto location = cast(size_t*) (cast(size_t) allocation.ptr + offset);

Expand All @@ -202,6 +206,35 @@ public class AndroidLibrary {
}
}

private void* buildStub(char* name) {
ubyte[] code = buildStubCode(name);
if (stubMaps.length == 0 || currentMapOffset + code.length > stubMaps[$ - 1].length) {
stubMaps ~= MmapAllocator.instance.allocate(pageSize);
currentMapOffset = 0;
}

void[] currentStubMap = stubMaps[$ - 1];

mprotect(currentStubMap.ptr, currentStubMap.length, PROT_READ | PROT_WRITE);
currentStubMap[currentMapOffset..currentMapOffset + code.length] = code;
mprotect(currentStubMap.ptr, currentStubMap.length, PROT_READ | PROT_EXEC);

void* address = &currentStubMap[currentMapOffset];
currentMapOffset += code.length;
return address;
}

private ubyte[] buildStubCode(char* name) {
// generates x86_64 assembler code for `undefinedSymbol(name)`
// it's never going to return back so we don't care about not saving registers.
import provision.symbols;
return [
ub!0x48, ub!0xBF, ] ~ name.ubytes() ~ [ // mov name %rdi
ub!0x48, ub!0xB8, ] ~ (&undefinedSymbol).ubytes() ~ [ // mov &undefinedSymbol %rax
ub!0xFF, ub!0xE0 // jmp *%rax
];
}

private string getSymbolName(ElfW!"Sym" symbol) {
return cast(string) fromStringz(&dynamicStringTable[symbol.st_name]);
}
Expand All @@ -210,14 +243,18 @@ public class AndroidLibrary {
return cast(string) fromStringz(&sectionNamesTable[section.sh_name]);
}

void* getSymbolImplementation(string symbolName) {
void* getSymbolImplementation(char* name) {
string symbolName = cast(string) name.fromStringz();
void** hook = symbolName in hooks;
if (hook) {
return *hook;
}

import provision.symbols;
return lookupSymbol(symbolName);
auto sym = lookupSymbol(symbolName);
if (!sym)
sym = buildStub(name);
return sym;
}

void* load(string symbolName) {
Expand Down Expand Up @@ -438,6 +475,14 @@ template R_GENERIC(string relocationType) {
enum R_GENERIC = mixin("R_" ~ relocationArch ~ "_" ~ relocationType);
}

template ub(ubyte a) {
enum ub = a;
}

ubyte[T.sizeof] ubytes(T)(T val) {
return *cast(ubyte[T.sizeof]*) &val;
}

size_t pageFloor(size_t number) {
return number & pageMask;
}
Expand Down Expand Up @@ -465,7 +510,7 @@ class LoaderException: Exception {
}

class UndefinedSymbolException: Exception {
this(string file = __FILE__, size_t line = __LINE__) {
super("An undefined symbol has been called!", file, line);
this(string symbol, string file = __FILE__, size_t line = __LINE__) {
super(format!"An undefined symbol has been called: %s."(symbol), file, line);
}
}
52 changes: 26 additions & 26 deletions lib/provision/compat/general.d
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
module provision.compat.general;

version (linux) {
import std.meta;
alias sysv = AliasSeq!();
} else {
version (Windows) {
version (X86) {
version = WindowsHacks;
}
version (X86_64) {
version = WindowsHacks;
}
}

version (WindowsHacks) {
version (LDC) {
import ldc.attributes;
import ldc.llvmasm;
enum sysv = callingConvention("sysv_abi");
} else version (GNU) {
import gcc.attributes;
Expand All @@ -15,35 +22,28 @@ version (linux) {
} else {
static assert(false, "Your compiler is not supported on your platform, please use LDC2 or GDC.");
}
}

version (Windows) {
version (X86) {
version = WindowsHacks;
}
version (X86_64) {
version = WindowsHacks;
}
}

version (WindowsHacks) {
import std.traits;
pragma(inline, false) auto androidInvoke(T, G...)(T delegate_, G params) {
void* del = cast(void*) delegate_;
pragma(inline, false) auto androidInvoke(alias U)(Parameters!U params) {
pragma(inline, false) extern(C) ReturnType!U internal(typeof(params)) @naked @sysv { // HACK
// asm {
// "jmp *%0" :: "r" (del);
// }
return __asm!(typeof(return))("jmp *%rax", "={rax}");
}

pragma(inline, false) extern(C) ReturnType!T internal(Parameters!T params, void* del) @naked @sysv { // HACK
asm {
"jmp *%0" :: "r" (del);
}
debug {
import slf4d;
getLogger().traceF!"calling %s"(__traits(identifier, U));
}

import slf4d;
getLogger().traceF!"Calling ? %x%s"(del, G.stringof);
import std.stdio;
stdout.flush();
return internal(params, del);
__asm("mov $0, %rax", "{rax}", U);
return internal(params);
}
} else {
import std.meta;
alias sysv = AliasSeq!();

pragma(inline, true) auto androidInvoke(T, G...)(T delegate_, G params) {
return delegate_(params);
}
Expand Down
36 changes: 36 additions & 0 deletions lib/provision/compat/macos.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
module provision.compat.macos;

version(OSX):

import core.stdc.errno;
import core.stdc.stdlib;
import core.stdc.string;
import core.sys.posix.fcntl;
import core.sys.posix.sys.stat;
import core.sys.posix.sys.time;
import core.sys.posix.unistd;

template traceCall(alias U) {
import std.traits;
import slf4d;
auto ref traceCall(Parameters!U params) {
getLogger().traceF!"CALL // %s"(__traits(identifier, U));
return U(params);
}
}

alias __errno_location = traceCall!(errno);
alias strncpy = traceCall!(core.stdc.string.strncpy);
alias lstat = traceCall!(core.sys.posix.sys.stat.lstat);
alias fstat = traceCall!(core.sys.posix.sys.stat.fstat);
alias malloc = core.stdc.stdlib.malloc;
alias free = core.stdc.stdlib.free;
alias gettimeofday = traceCall!(core.sys.posix.sys.time.gettimeofday);
alias open = traceCall!(core.sys.posix.fcntl.open);
alias close = traceCall!(core.sys.posix.unistd.close);
alias read = traceCall!(core.sys.posix.unistd.read);
alias write = traceCall!(core.sys.posix.unistd.write);
alias mkdir = traceCall!(core.sys.posix.fcntl.mkdir);
alias chmod = traceCall!(core.sys.posix.fcntl.chmod);
alias ftruncate = traceCall!(core.sys.posix.unistd.ftruncate);
alias umask = traceCall!(core.sys.posix.sys.stat.umask);
4 changes: 2 additions & 2 deletions lib/provision/compat/windows.d
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,11 @@ int lstat(const(char)* path, linux_stat* out_) {

uint mode = octal!555;

if (stat_windows.st_mode & octal!11) {
if (stat_windows.st_mode & 0b11) {
mode |= octal!200;
}

if (stat_windows.st_mode & octal!4000) {
if (stat_windows.st_mode & 0x4000) {
mode |= octal!40000;
}

Expand Down
6 changes: 3 additions & 3 deletions lib/provision/symbols.d
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ private @sysv extern (C) int emptyStub() {
return 0;
}

private @sysv extern (C) noreturn undefinedSymbol() {
throw new UndefinedSymbolException();
package @sysv noreturn undefinedSymbol(immutable char* symbol) {
throw new UndefinedSymbolException(symbol.fromStringz());
}

private @sysv extern (C) AndroidLibrary dlopenWrapper(const char* name) {
Expand Down Expand Up @@ -161,5 +161,5 @@ package void* lookupSymbol(string str) {
return wordlist[key].ptr;
}
}
return &undefinedSymbol;
return null;
}
7 changes: 6 additions & 1 deletion retrieve_headers/app.d
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,12 @@ int main(string[] args) {
auto otp = adi.requestOTP(-2);

import std.datetime.systime;
auto time = Clock.currTime();
version (Windows) {
import std.datetime.timezone;
auto time = Clock.currTime(UTC());
} else {
auto time = Clock.currTime();
}

std.stdio.writeln(
format!`{
Expand Down

0 comments on commit 6d3cc85

Please sign in to comment.