Once, while troubleshooting an online issue, I dropped my project’s IPA into class-dump and glanced at the output. Class names, method signatures, and parameter names were restored almost verbatim. For example, the output directly showed:

@interface PaymentManager : NSObject
- (void)startPayment:(NSString *)orderId userId:(NSString *)userId;
@end

This kind of information is already sufficient for reverse engineering. The interface structure, parameter meanings, and calling relationships can all be inferred. Later, I specifically implemented defenses against class-dump. The key is to make its output meaningless.


I. What class-dump Can Extract

Before processing, you can run it yourself:

class-dump AppBinary > dump.txt

Open dump.txt and focus on:

  • Class names
  • Method names
  • Parameter names
  • Protocol names

If you see:

UserManager
VipSubscriptionService
handleLoginWithUserId

It means symbols are fully exposed.


II. Reducing Symbol Information During Build

Adjust Release configuration in Xcode:

Strip Linked Product = YES
Strip Swift Symbols = YES

Rebuild and run:

class-dump AppBinary

The output will be reduced, but core class names still remain. This step cleans up debug symbols, but has limited effect on class-dump.


III. Identifying Symbols That Must Be Preserved

Before direct obfuscation, you need to identify parts that cannot be modified.

For example:

NSClassFromString("PaymentManager")

Or:

@objc(handleLogin:)

Methods that depend on strings or selectors will cause runtime errors if modified.

Approach:

  • Record these class names and methods
  • Exclude them from subsequent obfuscation

IV. Rewriting Symbols at the IPA Level

class-dump primarily relies on symbol information in the Mach-O binary.

To change the output content, you need to directly modify these symbols.

Ipa Guard, after loading the IPA, parses the binary and lists:

OC classes
Swift classes
OC methods
Swift methods

Code

In practice, we filter:

PaymentManager
UserCenterController
VipService

After obfuscation:

PaymentManager → a8d3k2

Run again:

class-dump AppBinary

The output becomes:

@interface a8d3k2 : NSObject

The structure remains, but semantics are lost.


V. Handling Method Parameters

class-dump output includes not only method names but also parameter names:

- (void)payWithOrderId:(NSString *)orderId userId:(NSString *)userId;

If only method names are changed, parameters can still provide clues.

Ipa Guard supports processing parameter names:

orderId → a1b2
userId → c3d4

After processing:

- (void)a8d3k2:(NSString *)a1b2 c3d4:(NSString *)c3d4;

class-dump output becomes hard to understand.


VI. Resource Files Can Also Aid Analysis

Even if symbols are obfuscated, resource files may still expose logic.

For example:

config/payment.json
assets/vip_banner.png

These files can help infer module structure.

In Ipa Guard’s resource module, you can:

  • Rename files
  • Update reference paths

After processing:
Rename

payment.json → k39sd.json
vip_banner.png → a82kd.png

Handling Resource Fingerprints

If multiple apps use the same resource, file contents may be compared.

You can enable MD5 modification:

md5 banner.png

md5

Before and after processing differ. This step changes resource characteristics, not content.


Deleting Debug Information (Reducing Additional Clues)

Besides class-dump, analysts also combine string information.

You can check:

strings AppBinary | grep NSLog

If log messages exist, they can be removed during processing.

Ipa Guard supports cleaning some debug content.


Supplement: JS / H5 Layer Processing

If the app contains WebView or React Native:

main.jsbundle
index.html

You can use:

terser main.js -o main.min.js

Minify and then combine with resource renaming.


Re-signing and Verification

After modifications, re-signing is required:

kxsign sign app.ipa \
-c cert.p12 \
-p password \
-m dev.mobileprovision \
-z test.ipa \
-i

Verify after installation:
Re-sign

  • Are pages normal?
  • Are dynamic calls effective?
  • Is functionality complete?

XI. Verify Processing Effect

Run again:

class-dump AppBinary

If the output becomes:

@interface a82kd3 : NSObject

It means processing is effective.


class-dump itself is not the problem; it is merely an entry point. The real issue is that the binary retains enough semantic information. As long as this information exists, any tool can exploit it.