burrowers / garble

Obfuscate Go builds
BSD 3-Clause "New" or "Revised" License
3.73k stars 239 forks source link

Potential pull request for gomobile support #810

Open digitalhurricane-io opened 8 months ago

digitalhurricane-io commented 8 months ago

I'm not reporting an issue so I hope it's ok if I skip the questions.

I'm interested in submitting a pull request that adds support for gomobile.

The commit message explains how it works: https://github.com/burrowers/garble/commit/0f03de874260d9678fdbccd91cc89167b8f230ac

However, it is not fully finished as it requires that no exported symbols are garbled. gobind generates bindings for exported symbols, so if those symbols are renamed, the bindings would not work. So the solution would be to not garble any exported symbols if the command is "garble mobile".

My questions are these:

A.) Are you open to a pull request like this?

B.) Do you think this is a good implementation?

C.) Do you see any pitfalls with this implementation?

D.) Are there any changes you would recommend?

E.) Are there any tests you would recommend writing?

F.) What would be the best way to add support for not garbling exported symbols if the command being run is "garble mobile"?

lu4p commented 8 months ago

Thanks for reaching out.

A) yes.

B) Seems fine to me.

C) Not really.

D) Please put the renamed garble binary into a temporary directory.

F) Search the commits for plugin support, that also required exported symbols to be left alone (plugin support has since been removed).

E) We would need an automated test (Github actions if possible) to build and run a gomobile app, which computes some value from the go code, which is then verified. (If you get stuck on this send the PR anyway we can help)

Are you sure all exported symbols need to stay intact or only main/root package symbols?

If all symbols need to stay intact, you'll also need to disable import path obfuscation.

If you need any assistance join us on slack, we're happy to help. (read CONTRIBUTING.md)

digitalhurricane-io commented 8 months ago

Awesome.

The temp dir is a good idea, I will do that.

I'll start looking into E after I get F done.

I am not sure if all exported symbols need to stay intact. I believe only the symbols from the main/root package.

digitalhurricane-io commented 8 months ago

I have "gomobile bind" working for android for generating mobile libraries. Still untested on iOS, but I will do that soon.

Building an actual android app with "gomobile build" will not work with this implementation. Immediately after the binary is built, gomobile tries to read the symbols from the binary, but since they have already been stripped, that fails.

Offending code: https://github.com/golang/mobile/blob/35478a0c49da882188b186a3893d45be6ff74327/cmd/gomobile/build_androidapp.go#L87

Personally, I only need the bind command for generating libraries. And I feel that libraries are a much more common use case than building a full blown mobile app with go. I would guess that's pretty uncommon.

Since I have accomplished my use case, I can't justify going any farther on "gomobile build" as it would require a different implementation.

So the question is, are you still interested in a pull request that only supports "gomobile bind"?

The latest code: https://github.com/burrowers/garble/commit/9717b90290285ff9a35025f8bf6db0762f72e95c

digitalhurricane-io commented 8 months ago

Well, I guess the same PATH redirection technique could be used for the tool gomobile is calling here: https://github.com/golang/mobile/blob/35478a0c49da882188b186a3893d45be6ff74327/cmd/gomobile/build_androidapp.go#L87

And then pipe gomobile the package names it expects. That would at least get past that obstacle.

lu4p commented 8 months ago

I think gomobile bind is way more common anyway, I don't think many people really build full go mobile apps.

Happy to review your PR.

pagran commented 8 months ago

Well, I guess the same PATH redirection technique could be used for the tool gomobile is calling here: https://github.com/golang/mobile/blob/35478a0c49da882188b186a3893d45be6ff74327/cmd/gomobile/build_androidapp.go#L87

And then pipe gomobile the package names it expects. That would at least get past that obstacle.

Getting the list of packages works on regex, maybe it's possible to add the list to the end of the binary ( just as text at the end) and then delete it? If the build system allows it, of course

digitalhurricane-io commented 8 months ago

@pagran That's a clever idea. I think I'm just going to stick with "gomobile bind" though and not worry about "gomobile build".

lu4p commented 7 months ago

@digitalhurricane-io any updates?

From what I can tell your implementation for gomobile bind is complete, no?

@Mrs4s maybe you can help test this for iOS?

digitalhurricane-io commented 7 months ago

I found a couple issues.

The -debugdir flag no longer works. I have to decide how to fix that.

Also I was sometimes getting an error when trying to run an obfuscated binary relating to a package not being found. Clearing the build cache and recompiling seemed to fix it.

So it still needs some work. I've got some more urgent tasks to work on at the moment. I am still planning on circling back around to this in maybe a month.

lu4p commented 7 months ago

Thanks for the update!

Mrs4s commented 7 months ago

@digitalhurricane-io any updates? 

From what I can tell your implementation for gomobile bind is complete, no?

@Mrs4s maybe you can help test this for iOS?

I haven't utilized Go Mobile for adapting to mobile platforms, so my experience in that area might not be particularly relevant. However, my approach involves compiling Go into a C library and then employing linking with iOS or using JNI with Android to facilitate support for mobile platforms

I am currently in the process of testing the compatibility of this method with Garble. Should there be any further developments, I will make sure to update this issue with the new information.

digitalhurricane-io commented 6 months ago

I got the -debugdir flag working again by saving the flags in an env var and reloading them when garble is called by gomobile as 'go'.

https://github.com/digitalhurricane-io/garble/commit/8489e779b9e2507471993ed84b77d756b8f8e94d

However garble reverse does not successfully reverse any hashes. I'm not quite sure the best way to go about debugging this.

I was hoping there might be something obvious to you guys about how this implementation could affect garble reverse? Or maybe you have some tips on debugging this aspect?

Update: pkg.BuildID is different during obfuscation and reversing. The question is why.

Reversing with a seed works as expected.

Update 2: adding the proper GOOS and GOARCH allows for reversing the standard library, but not my code: GOOS=android GOARCH=arm64 garble reverse -buildmode=c-shared . ./panic-output.txt