AM2R-Community-Developers / AM2RLauncher

Host respository for the AM2RLauncher.
GNU General Public License v3.0
372 stars 19 forks source link

PATCHOPENSSL needs to be updated for 64 bit AM2R 1.6 #56

Open SuperSamus opened 1 year ago

SuperSamus commented 1 year ago

Describe the bug PATCHOPENSSL is an option meant for Linux distributions that don't offer OpenSSL 1.0.0 (because it's old and insecure). 5d8b7d9b3de68e6215c10b9fd223b7f1d5e40dea When using the new 64 bit AM2R 1.6 beta, however, the executable is patched incorrectly. EDIT: Forgot to specify that I'm also using NOAPPIMAGE.

Expected behavior The executable is patched correctly, and can be launched.

To Reproduce Steps to reproduce the behavior:

  1. Be on Linux
  2. Compile the launcher with PATCHOPENSSL
  3. Use the new 1.6 beta (which is 64 bit)
  4. Patch it with the launcher, and try to launch it

Platform

Log file

When the runner is launched, it logs (to gather the logs, I launched it outside the launcher):

/home/user/.local/share/AM2RLauncher/Profiles/AM2R 1.6 Beta/.runner-unwrapped: /lib64/libcurl.so: no version information available (required by /home/user/.local/share/AM2RLauncher/Profiles/AM2R 1.6 Beta/.runner-unwrapped)
/home/user/.local/share/AM2RLauncher/Profiles/AM2R 1.6 Beta/.runner-unwrapped: /lib64/libcurl.so: no version information available (required by /home/user/.local/share/AM2RLauncher/Profiles/AM2R 1.6 Beta/.runner-unwrapped)
/home/user/.local/share/AM2RLauncher/Profiles/AM2R 1.6 Beta/.runner-unwrapped: /lib64/libcurl.so: no version information available (required by /home/user/.local/share/AM2RLauncher/Profiles/AM2R 1.6 Beta/.runner-unwrapped)
/home/user/.local/share/AM2RLauncher/Profiles/AM2R 1.6 Beta/.runner-unwrapped: symbol lookup error: /home/user/.local/share/AM2RLauncher/Profiles/AM2R 1.6 Beta/.runner-unwrapped: undefined symbol: X509_free, version OPENSSL_1.0.0
Miepee commented 1 year ago

@peeley can you look into this? You should be able to get the runner and data file from here: https://github.com/AM2R-Community-Developers/ProfessorG64/releases

Maybe we'll need some hash check on whether we have the old runner before running patchelf on it. Not sure. Could also be that the new runner still uses outdated openssl, I have not had the time yet to look at it.

Miepee commented 1 year ago

Also just to make sure, @SuperSamus can you patch this without the OPENSSL flag to ensure it's actually a problem of what we do with patchelf, rather than your local dependencies? As the 1.6 requires a few different ones.

SuperSamus commented 1 year ago

Without the OPENSSL flag I can't launch the runner because I'm missing libcrypto.so.1.0.0 and libssl.so.1.0.0. My distribution doesn't offer these libraries, so I had to forcefully download them and LD_LIBRARY_PATH them. Doing that, the game starts.

All of this using the same dependencies I was using before (but 64 bit instead of 32 bit).

Miepee commented 1 year ago

and just as double confirmation, if you LD_LIBRARY_PATH those libs with the OPENSLL flag, it still gives the same error, right?

SuperSamus commented 1 year ago

Exactly.

peeley commented 1 year ago

@peeley can you look into this? You should be able to get the runner and data file from here: https://github.com/AM2R-Community-Developers/ProfessorG64/releases

Sure, I'll take a look. There's no README for that repo, so I assumed that all I needed to do was unzip the release .zip file into the data directory of the patcher; I hope I'm doing that correctly.

I'm able to reproduce the issue as well, although I haven't tried the LD_LIBRARY_PATH workaround. Here's an idea, although a pretty ugly and hacky one - support for OpenSSL 1.0.0 is pretty rare these days, but AM2R relies on it fairly heavily. Might we just check a copy of the required .so files into this repo, so they can be reliably copied in instead of relying on distro package repositories? We would need to update the launcher and the README instructions in this repo (for the non-AppImage flow), though.

SuperSamus commented 1 year ago

Alternatively to LD_LIBRARY_PATH, there is:

patchelf --set-rpath '$ORIGIN/lib' .runner-unwrapped

Where inside the profile you put a lib folder with the 64 bit libraries libcrypto.so.1.0.0 and libssl.so.1.0.0.

Seriously, this is horrible...

Miepee commented 1 year ago

Sure, I'll take a look. There's no README for that repo, so I assumed that all I needed to do was unzip the release .zip file into the data directory of the patcher; I hope I'm doing that correctly.

Sorry, I completely forgot to provide installations instructions <-< Doing it that way is the wrong approach. The correct approach would be to open the am2rlauncher -> mod settings tab -> add new mod -> select the zip. The process is also documented on the (somewhat obscure) FAQ: https://am2r-community-developers.github.io/DistributionCenter/faq.html#how-do-i-install-mods

peeley commented 1 year ago

The correct approach would be to open the am2rlauncher -> mod settings tab -> add new mod -> select the zip. The process is also documented on the (somewhat obscure) FAQ: https://am2r-community-developers.github.io/DistributionCenter/faq.html#how-do-i-install-mods

Thanks, I was able to do that and observe the same behavior. The game crashes and complains about a missing symbol for OpenSSL.

Seriously, this is horrible...

Yeah, I hate it too :(. Unfortunately, there seems like no other realistic workaround other than AppImage (which is not an option for distros like NixOS). I've made a branch of the launcher that depends on another branch of the patcher as a rough proof of concept, that does just this. I'm able to start the launcher, add 1.6 beta as a mod, install, and start the game.

Let me know if it also works on your machines, and if it's a viable path forward. Apologies if there's any glaring errors, btw - I'm fairly ill at the moment.

Lojemiru commented 1 year ago

For what it's worth, the wrapper we're using for 1.6 is a few versions behind the theoretical maximum version number to which we could climb. It is possible, though by no means guaranteed, that the theoretical maximum could be using a newer version of openssl. It's on my list to go see if I can find a clean set of game wrappers for that maximum version number, but 1.6 development has stalled for the moment due to higher priority items in my day-to-day.

peeley commented 1 year ago

It is possible, though by no means guaranteed, that the theoretical maximum could be using a newer version of openssl.

That would be super nice. Even a relatively small bump up to OpenSSL 1.1 would make things much easier when it comes to packaging.

Miepee commented 1 year ago

Might we just check a copy of the required .so files into this repo, so they can be reliably copied in instead of relying on distro package repositories?

Unless we can absolutely not find a workaround, I would very much try to avoid this as much as possible.


I would try to see if maybe one has to provide different patchelf arguments. I know the previous version of the runner didnt use curl/openssl at all, I'm not sure if this is still the case here. I'll go see if i can reach Ivar, she was the one who initially pushed this forward.

peeley commented 1 year ago

Huh, I was just able to launch the 1.6 beta after tweaking the .runner-unwrapped with patchelf to clear some symbol version info:

$ patchelf .runner-unwrapped --clear-symbol-version X509_free

The X509_free function seems to be the only OpenSSL function that's getting called, so telling the binary to not care about the library version seems to get things working.

I have a branch for the launcher that's working so far. If it checks out for you all as well, I can make a PR.

Lojemiru commented 1 year ago

I'm not entirely sold on just removing that symbol without further context since we want to ensure that the multiplayer mods can update to 1.6 as well. Base AM2R may not touch any part of GameMaker that uses that function, but given that it's OpenSSL I would anticipate that the network functions may do so. Any idea what operations the function in question is being used for?

peeley commented 1 year ago

It's not actually removing the symbol in question, it's just removing the version information from it. That being said, since we're already patching OpenSSL 1.0.0 with libcurl, I can't vouch that it still functions 1:1.

I can only guess what the function does without reading the source, but it looks like it's something to do with allocating/deallocating C structs from memory that represent X509 certificates for SSL/TLS connections (docs).

Lojemiru commented 1 year ago

Ah, thank you for the clarification. Intriguing that there's a call to free this structure but not one to instantiate the same structure under this specific version... I'll leave the final call up to Miepee, as this is much more his realm of expertise, but that all sounds reasonable enough to me for now.

SuperSamus commented 1 year ago

I have a branch for the launcher that's working so far. If it checks out for you all as well, I can make a PR.

Tested the branch on both 32 bit and 64 bit AM2R, game launches on both.

Miepee commented 1 year ago

I have a branch for the launcher that's working so far. If it checks out for you all as well, I can make a PR.

Ayyy, nice. Based on SuperSamus' description above, sounds like you dont even need to check for different runners. So I don't mind if you'd open a PR for both the linux patcher and from that launcher branch.

Altho i do wonder if this is actually true now:

I know the previous version of the runner didnt use curl/openssl at all

I did look at it in ghidra aaages ago. Based on DMs with Johnny, it seems that openssl is only used if a game maker game uses the http functions (https_request, http_get, https_get_file, http_post_string). Current multitroid to my knwoedge doesn't use these, and neither some other network based GM games like metroid planets do AFAIK. as these functions are only useful for interacting with a webserver. But if anyone wants to try it out: here's the server and client for miles' last multitroid version. Ideally run the server on a machine of yours (you probably need to manually patch the binary to get rid of openssl), then have two machines with patched openssl try to connect to it. I'll see if i can make that version go through the 1.6 scripts to have a 64bit PoC. If yes, i'll go post that in here (or in the PR if its made) and ask for another test run by you.

peeley commented 1 year ago

But if anyone wants to try it out: here's the server and client for miles' last multitroid version. Ideally run the server on a machine of yours (you probably need to manually patch the binary to get rid of openssl), then have two machines with patched openssl try to connect to it.

Downloaded the server release, unzipped it, and ran:

patchelf AM2R_Server \
                  --replace-needed "libcrypto.so.1.0.0" "libcurl.so" \
                  --replace-needed "libssl.so.1.0.0" "libcurl.so" \
                  --clear-symbol-version X509_free

It was able to launch and run without a hitch. I also downloaded Multitroid as a mod, and got it to launch and run. I was able to get two clients (one on the same machine as the server, I don't have three different Linux machines to test from unfortunately) connected and playing in multiplayer as expected.

I hadn't played Multitroid before; I'm actually pretty surprised how simple it was to set up and how seamless the experience was. All I needed to do was edit the server IP and the display name in each client, and it was smooth sailing.

Miepee commented 1 year ago

Have been experimenting with a 64bit version of multitroid, had not much success, so will document the process here. To patch the client:

  1. Download the 1.4 release of multitroid linked above. Not 1.4.2.
  2. Clone the PG64 repo: https://github.com/AM2R-Community-Developers/ProfessorG64
  3. Usage instructions is ./CLI-ubuntu-latest-Release-isBundled-true/UndertaleModCli load -s ProfessorG64.csx -o game.unx [path-to-original-game.unx] where [path-to-original-game.unx] can look something like ./multitroid-1-4-0/assets/game.unx
  4. Move the newly created game.unx and replace the original file with it.

To patch the server:

This will give you a patched game.unx file. You'll also need a patched runner, which you can get from either the 1.6 beta, or from the linux version of the out of clay mini jam


At this point, I am able to run both the server and the client. however, attempting to connect to the server, just times out. Looking at wireshark, it does capture two packets, but I'm currently not knowledgeable enough to figure out what the packets exactly do:


out of curiosity, I also tried running your patchelf command on it, but then i just got hit with:

./runner: /usr/lib/libcurl.so: version `OPENSSL_1.0.0' not found (required by ./runner)
./runner: /usr/lib/libcurl.so: version `OPENSSL_1.0.1' not found (required by ./runner)
./runner: /usr/lib/libcurl.so: version `OPENSSL_1.0.0' not found (required by ./runner)

I don't think I have missing dependencies (got both (lib32-)openssl-1.1 and openssl-1.0 from the AUR), especially since it works without patchelf. But y'all are probably able to judge it better.

peeley commented 1 year ago

Hmm, I'm getting a weird crash on launch with the 1.4 version of the server. Whether unpatched or patched for 64-bit using the directions above, it seems like the server opens a window and then immediately crashes. Not sure if it means anything, but it seems to be consistently segfault before the Background_InitTextures() line would typically appear in stdout. I can't glean much from the Multitroid repo; what changes could there have been between 1.4 and 1.4.2? I'm wondering if I'm just missing a dependency or something that might have been changed between versions.

I don't think I have missing dependencies (got both (lib32-)openssl-1.1 and openssl-1.0 from the AUR), especially since it works without patchelf.

I'm guessing this might be an issue with symbol versioning information. Some distros strip version info from packaged .so files, others don't. Unfortunately, I can't say for sure until I get the server running myself and try to reproduce the issue.

Also - might we move the multiplayer discussion to a separate issue? It seems like the original problem with running the 1.6 beta has been more or less solved.

Miepee commented 1 year ago

opened an issue at PG64, lets continue the multitroid specific discussion there