Skip to content

Commit

Permalink
* Add shell scripts to easily build OpenSSL for use with DM.
Browse files Browse the repository at this point in the history
  • Loading branch information
iProgramMC committed May 8, 2024
1 parent 067fbc0 commit 58e7bf8
Show file tree
Hide file tree
Showing 4 changed files with 162 additions and 0 deletions.
44 changes: 44 additions & 0 deletions BUILD-DM.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Building OpenSSL

You want to check out Discord Messenger? Well you're probably going to want to compile OpenSSL,
so I've provided some shell scripts to make it easier to build.

The main command to run is:
```
./buildit
```

Note: You will need Mingw-w64, and specifically the mingw32 shell. You'll also need to follow
the [notes on Windows](NOTES-WINDOWS.md) regarding the packages to install.

### Configure

The script configures OpenSSL to:
- compile with MinGW
- not include any assembly blobs (makes it not use advanced instruction sets such as SSE2)
- defines `WINVER` and `_WIN32_WINNT` as `0x0501` (to avoid OpenSSL targeting Vista+ APIs)
- defines `OPENSSL_THREADS` to allow OpenSSL to use threads
- defines `OPENSSL_NO_ASYNC` and `OPENSSL_USE_NODELETE` to avoid OpenSSL importing certain Vista+
APIs

### Build

Then, it runs `make -j$(nproc)`. It takes the number of logical processors in your system, and
runs a make job for each. This allows a faster build while not totally blowing up your computer
(as `make -j` would do - unboundedly spawn jobs)

### Patch to remove a single XP+ import

Finally, it runs `./patchlibcrypto`, which compiles a single C file, `./patchlibcrypto.c` to a temp
file, runs it, and deletes it. `patchlibcrypto.c` patches libcrypto-3.dll to change imports to
`_strtoi64` and `_strtoui64` to `iswxdigit` and `isleadbyte` (functions likely to return zero given
the parameters, and have the same length, and are also exported by msvcrt.dll), by doing a dumb
binary search.

Note: Ideally I'd remove all uses of \*scanf, though not totally sure that'll remove the import
patch requirement.

Note: This patch step is optional if you don't intend to run Discord Messenger on Windows 2000 or
older.

-iProgramInCpp
11 changes: 11 additions & 0 deletions buildit
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/sh
# Build script for OpenSSL targeting Windows 2000 (and older).

# run the configure script.
perl ./Configure mingw no-asm -DWINVER=0x0501 -D_WIN32_WINNT=0x0501 -DOPENSSL_THREADS -DOPENSSL_NO_ASYNC -DOPENSSL_USE_NODELETE

# Make
make -j$(nproc)

# Patch libcrypto.dll
./patchlibcrypto
8 changes: 8 additions & 0 deletions patchlibcrypto
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/sh

# Compile patchlibcrypto.c into a temporary file, run it, and then delete it.
TEMPFILENAME=$(mktemp)
echo Compiling patchlibcrypto.c to $TEMPFILENAME.exe
gcc patchlibcrypto.c -o $TEMPFILENAME.exe
$TEMPFILENAME.exe
rm $TEMPFILENAME
99 changes: 99 additions & 0 deletions patchlibcrypto.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

void* find_memory(void* haystack, size_t size_haystack, const void* needle, size_t size_needle)
{
if (size_needle > size_haystack)
return NULL;

char* haystack_ptr = haystack;
for (size_t i = 0; i < size_haystack - size_needle + 1; i++) {
if (memcmp(haystack_ptr, needle, size_needle) == 0)
return haystack_ptr;

haystack_ptr++;
}

return NULL;
}

int main()
{
FILE *f = fopen("libcrypto-3.dll", "rb");
if (!f) {
perror("could not open libcrypto-3.dll");
return 1;
}

long size;
fseek(f, 0, SEEK_END);
size = ftell(f);
fseek(f, 0, SEEK_SET);

if (size < 0) {
perror("libcrypto-3.dll is not a file or something");
fclose(f);
return 1;
}

char* fdata = malloc(size);
if (fread(fdata, 1, size, f) != size) {
perror("could not read entire file libcrypto-3.dll");
fclose(f);
return 1;
}

fclose(f);

char* strtoi64_place = find_memory(fdata, size, "_strtoi64", 9);
char* strtoui64_place = find_memory(fdata, size, "_strtoui64", 10);

if (!strtoi64_place) {
fprintf(stderr, "cannot find _strtoi64 in libcrypto-3");
return 1;
}
if (!strtoui64_place) {
fprintf(stderr, "cannot find _strtoui64 in libcrypto-3");
return 1;
}

memcpy(strtoi64_place, "iswxdigit", 9);
memcpy(strtoui64_place, "isleadbyte", 10);

f = fopen("libcrypto-3-patched.dll", "wb");
if (!f) {
perror("cannot open libcrypto-3-patched.dll for writing");
return 1;
}

if (fwrite(fdata, 1, size, f) != size) {
perror("cannot write all bytes to libcrypto-3-patched.dll");
fclose(f);
return 1;
}

fclose(f);

// perform the swap
if (rename("libcrypto-3.dll", "libcrypto-3-original.dll") < 0) {
if (errno == EEXIST) {
// delete the file
if (remove("libcrypto-3-original.dll") < 0) {
perror("couldn't delete old libcrypto-3-original.dll to rename the actual original over");
return 1;
}
}
else {
perror("cannot rename libcrypto-3.dll to libcrypto-3-original.dll");
return 1;
}
}
if (rename("libcrypto-3-patched.dll", "libcrypto-3.dll") < 0) {
perror("cannot rename libcrypto-3-patched.dll to libcrypto-3.dll");
return 1;
}

return 0;
}

0 comments on commit 58e7bf8

Please sign in to comment.