Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Initrode.Hack()

 Initrode.Hack()

How we cracked those old releases *of our own app*...

Avatar for Patrick Martin

Patrick Martin

May 30, 2015

Other Decks in Programming

Transcript

  1. The Rules Names/details have been changed to protect the guilty

    Audience Participation is welcome Although, please “no spoilers” if poss. Finally “Please don’t judge me”
  2. It was the best of times, Initrode had a “well-loved”

    Windows desktop application Had semantic versioning (maj,min,patch) Policy of support for current + LTS Essentially subscription based revenues And had a fairly modular design...
  3. it was the worst of times It was also the

    initial throes of the GFC Suddenly “automated testing is popular” An internal tool was re-purposed to provide a testing front end / runner And now, we need to ship it to the customers
  4. Know your customers The only problem with shipping to the

    customers is who they are. Large outfits like insurance companies that have: • important pre-existing installations • long lead in times for testing • Sarbanes Oxley constraints on system changes • a variety of installed versions
  5. So what’s the issue? Simply adding it to the next

    version could mean waiting years for the customers to upgrade Really not an option to wait (people are trying to improve their models, and soon) Really not an option to modify existing installations
  6. The Rolls-Royce Solution A drop-in Application sitting on top “Just

    do what I want” [More context] • there was a collection of components with a pretty stable API that had been in place for some time • Allows scripting languages / Excel to run models • Allows other apps to drive model runs
  7. “Not so fast, pardner” But, security had been thought of

    (subscription revenue, remember?) There was a hardware dongle providing security and - via an API component - crucially authorising components to run
  8. Quick review of security solutions If you want to prevent

    your app/ binary from being run. Someone needs to return non-zero from dllmain at application startup There are hardware solutions that will do this. A less strong approach is have a driver for the hardware that verifies there is a dongle present after process start
  9. Quick Review of IniTrodeSecurity.dll Apps link to the runtime in

    process, then ask it if it will run the runtime is linked to the security component, which queries the hardware dongle and asks it if it authorised to run the passed in application ID the security component gets a "magic question" from runtime security component returns a “magic answer" All good!
  10. Example: runtime pass static link https://github.com/patrickmmartin/Initrode.Hack/ $app_cheat App_cheat start B

    Loaded ... not really! A_static Loaded B_.SecretFunction SecretFunction: 42
  11. Homing in Making changes without modifying on-disk. Well, there are

    techniques… • Shim dlls • Detours • IAT patching • Alternate load paths IAT patching works for all OSes we needed
  12. Attempt #1 Find the the import for MagicQuestion() in the

    IAT of A.dll and overwrite with a function that lets the test app in. Fits all the requirements right?: • localised to a new drop-in app • does not impact existing runtimes • works with a range of release versions Only one problem - didn’t work
  13. Attempt #1 Find the the import for MagicQuestion() in the

    IAT of A.dll and overwrite with a function that lets the test app in. Fits all the requirements: • localised to a new drop-in app • does not impact existing runtimes • works with a range of version Only one problem - didn’t work
  14. Attempt #2 “What if we just hook GetProcAddress()” Why that’s

    “just crazy talk” … And why that in fact, worked.
  15. Attempt #2 Process achieves this by loading the module for

    A.dll - replace GetProcAddress() with a hook that passes through the result (by name) except for our target functions, where we return substitute function pointers. Of course, matching in parameters and calling convention.
  16. Example: dynamic link hooking https://github.com/patrickmmartin/Initrode.Hack/ $app_subvert A_dynamic loaded App subvert

    start GetProcAddress hooked B Loaded Hooking SecretFunction MySecretFunction SecretFunction: 42
  17. Conclusions Preamble This is not a massively sophisticated fix. It

    does however, “just work” with the minimum of fuss.
  18. Example: altered search path https://github.com/patrickmmartin/Initrode.Hack/ $app_subvert2 App_subvert2 start B Loaded

    ... not really! A_tough loaded Locating SecretFunction B_.SecretFunction SecretFunction: 42
  19. Conclusion (cont.) So waddya think? Could we have done it

    differently? Should we have done it differently? Any other comments?
  20. Conclusion (concluded) That was it! Thanks for listening. if !$(tough

    crowd) thanks for the participating in the fun
  21. Conclusion (concluded) That was it! Thanks for listening. if $(tough

    crowd) thanks for the constructive criticism
  22. Feedback Your feedback is important! Please be as honest as

    you want (Using the supplied application)
  23. Feedback type TFeedback = [1..10]; function MyGetFeedbackScore(cookie: Integer): TFeedback; stdcall;

    // important begin Return High(TFeedback); end; initialization var FeedbackModule : HINSTANCE; FeedbackModule := LoadLibrary('Feedback.dll’); HookFunction(FeebackModule, 'GetFeedbackScore', @MyGetFeedbackScore);