Preferred way / Design pattern to handling complex configuration on iOS - objective-c

Suppose that you need to have a series of complex configuration for a series of different Objects. This configuration can be NSString like service's server address, NSNumber like timeout time and so on. I want to impose the following constraint:
Configuration must not be visible and/or editable to user so plist in the app bundle is not an acceptable solution
I need different configuration value for debug, AdHoc or release target (I will likely achieve this with a series of #ifdef but i write for sack of completeness)
All the object that i want to configure belongs to a Static Library and i want to inject the configuration from the code that use this static library (inject is in italic as my personal hint to a dependency injection)
My question is: what's the best way to achieve this? Have you ever faced a problem like this? how did you solve it?

Take advantage of Xcode build system. You can have Xcode configuration files for any build configuration (Debug, Release, etc) and target combination.
These files support inheritance to simplify sharing configuration. There is no a single way to define the options. A simple one is to use GCC_PREPROCESSOR_DEFINITIONS or CFLAGS or whatever your compiler will take.
TargetX.xcconfig:
GCC_PREPROCESSOR_DEFINITIONS = STAGE=2 SERVER_URL='www.wuonm.com'
With configured values is fairly trivial to build the required NSString or NSNumber objects. Tip: you will require some kind of stringification.
It's quite similar to using #define but IMHO it's much cleaner and structured if you invest some time understanding how xcconfig files work.

If these values are constant for each build configuration, why not put them in your code as constants? I don't really see why you need to externalize these settings if they are constants that vary by config. Your ifdef selection of the settings would be just as effective (and faster) with these constants declared in a private header.
If these settings somehow change during the running of the app (not from build to build but within the confines of running a single build of the app) then externalizing these settings would be appropriate.

There are many questions that arise with this post:
Why do you need this level of protection on your input configuration?
Is the point that you dont wish the user to be able to modify your configuration, or is it that you dont wish them to be able to KNOW it at all?
If you beleive the theory that SW cannot protect SW, then truly what level of pain are you willing to put yourself through in order to put the hacker through enough pain they dont want to hack your SW (because lets face it, thats all you are really going to get, see my comments above about encryption)
I somewhat agree with getting your configuration from the internet, but this only will work IFF you are expecting an internet capability present in order to use your app. If you do this and you also want some level of protection then you are going to have to use some secure protocol (Like SSL) for downloading it.
If you truly wish your app to be able to be used locally (without internet access), then I would say that true security of your configuration is simply immposible, as you dont control the OS, your dont control the HW your SW is running on, etc...
Putting your app on the iPhone probably means that you are hoping for a fairly large amount of downloads. This means the amount of hands touching it and potentially being able to take a CRACK at it are also large. The only way to gain security in this case (as no SW really is), is to make the value of hacking it to get your configuration not worth all that much. If the value is low, then no hacker will care to try and crack it!

I faced this same issue with server URLs used in different classes and constant numbers like colors, sizes and pretty much any configuration needed to be easily changed. The best solution I found was creating a header file like Constants.h, the content of this header file was:
#define MAX_DIST 1000
#define MIN_DIST 300
#define ANIMATION_DURATION 0.010
#define PIXEL_MOVES 7
#define SENSITIVITY 14
#define VIEW_ANGLE 30 //Range of vision divided by 2
#define RAD_POS_X 415
#define RAD_POS_Y 15
#define BUTTON_VIEW_WIDTH PIXEL_MOVES*360
#define SCREEN_HEIGHT 480
#define BUTTON_WIDTH_CLOSE 180
#define BUTTON_HEIGHT_CLOSE 100
#define BUTTON_WIDTH_MEDIUM 100
#define BUTTON_HEIGHT_MEDIUM 60
#define BUTTON_WIDTH_FAR 60
#define BUTTON_HEIGHT_FAR 40
#define BUTTON_Y_POSITION_CLOSE 200
#define BUTTON_Y_POSITION_MEDIUM 135
#define BUTTON_Y_POSITION_FAR 90
#define SERVICE_URL #"http://my.server.com/SoapServer/SoapServiceWS"//
you can even define common functions like
#define DEGREES_TO_RADIANS(__ANGLE__) ((__ANGLE__) / 180.0 * M_PI)
This way i have been able to configure every aspect of my app from one single file and you can use #ifdef like you said to manage different compilations. Of course, you must import the file Constants.h in any class that will need to access any of these constants.

Your static library should provide some interface to set current configuration that will be set in runtime.
SetCurrentConfiguration(Configuration config);
Then "client" can configure it with needed configuration in runtime.
Second step is load configuration from specified source, let's say xml file and inject it to static library via method above.
If you don't want users to modify configuration files you can use some sort of encryption and then decrypt on the fly.

Require that for the first time use, an internet connection is present and download via HTTPS your config and keep it in memory (encrypted if you want).
Then take advantage of the keychain in iOS, and store your config as a string there (essentially serialize it).
NSString *serializedConfig = ...;
[keychain setObject:serializedConfig forKey#"MyConfig"];
On subsequent use, retrieve the config stored in the keychain:
NSString *serializedConfig = [keychain objectForKey:#"MyConfig"];
You can find the keychain wrapper and documentation on the Apple Docs site.

Related

Objective-C framework which can be adjusted in compiling time

More detailed explanation (for smaller version, check TL;DR in the end):
I created a framework that I made available in Github. In it, there are 7 Macros that define how the framework should be compiled. I can't just replace them with static const's because 6 of those Macros are used to remove some things from the framework in compiling time.
Those Macros may be divided in groups:
Group 1) Use framework when available
#define USE_THE_METAL_FRAMEWORK_WHEN_AVAILABLE true
#define USE_THE_OPENGL_FRAMEWORK_WHEN_AVAILABLE true
Those defines make the framework use the Metal and OpenGL frameworks even if they weren't added to the project. That's done using dlopen. More details below:
https://stackoverflow.com/a/24266440/4370893
https://stackoverflow.com/a/21375580/4370893
https://stackoverflow.com/a/1354569/4370893
I use this so those frameworks can be used only if they are available, so the dev can build his/her app for macOS 10.6 and still use Metal if it's available in the system. The problem is: if your app binary calls dlopen somewhere, you can't add it to the Apple Store (even if you don't really use the function that uses it), so users should be able to remove that from the code if they want. That removes some of the framework functionalities, but make it capable of being submitted.
Group 2) I'm importing the framework
#define IM_IMPORTING_THE_METAL_FRAMEWORK false
#define IM_IMPORTING_THE_OPENGL_FRAMEWORK false
Those defines make the framework really use Metal and OpenGL frameworks, without using dlopen. In that way, it can be submitted to the Apple Store and still use the features that were mentioned before.
Group 3) Behaviour changes
#define USER_NOTIFICATIONS_SHOULD_SHOW_A_BIGGER_ICON true
#define NSDEBUGLOG_SHOULD_PRINT_TO_A_DESKTOP_FILE_TOO true
The first one can also cause problems in the Apple Store, and the second one is only for debugging purposes.
And at last...
Group 4) Should be released in the Apple Store
#define I_WANT_TO_BE_RELEASED_IN_APPLE_STORE false
That one is used for that:
#if I_WANT_TO_BE_RELEASED_IN_APPLE_STORE == true
#define USER_NOTIFICATIONS_SHOULD_SHOW_A_BIGGER_ICON false
#define USE_THE_METAL_FRAMEWORK_WHEN_AVAILABLE false
#define USE_THE_OPENGL_FRAMEWORK_WHEN_AVAILABLE false
#endif
It automatically disables the three defines that may cause problems with the Apple Store.
Still, those who use Travis-CI for example are not capable of changing the framework unless they completely copy it to the project. To solve this problem (or at least reduce it), 5 of those 7 defines could be changed by a file in the main project, for example. If anyone has other suggestions that may solve the issue, I'm listening.
(Optional) If this could be done in a way that the user may be warned (by Xcode or by an error in compiling time) that he/she needs to set those variables that would be great, since this would avoid problems with users that may need to set those Macros.
TL;DR: Is it possible to change the values of some Macros within a framework without modifying the framework itself?
No. Make some method, that initialize yours module with some parameters. But anyway you are not able to use dlopen.

Can variables in memory by made immune to malicious memory editing?

Let's say I am making a game and the player's health is stored in a variable float player_hp. While playing the game, a user can open a memory editor like Cheat Engine, do some clever searches through the memory, and find the location of the variable in memory. They can then edit it to be whatever they want, effectively allowing them to cheat.
Is there a fancy way to store my variables that will effectively stop users from maliciously editing them? Should I move them around in memory? Should I encrypt them or hash them?
If it matters, I am primarily using C++.
Disclaimer: I have no experience programming games, only making cheats for them.
Calculate all important variables such as health & ammo server side and replicate that data to the client. Pickups must also be validated by the server. If you serverside ammo, we'll just call PickUp(ammoCrate) if it's client sided.
You'll never stop everyone but I think it's important to make it annoying enough for 90% of people to stop trying to cheat. There's some basic stuff every game should have and then more advanced protections that popular games must have to avoid being destroyed by cheaters.
Encrypt commonly modified values such as health with a basic XOR like algorithm that changes over time. Change address of the key also and use a pointer to it, make the pointer more than 6 layers deep. This will force cheaters to make a script and use pattern scanning instead just a cheat table, that will stop most people.
Use IsDebuggerPresent() to detect debuggers being attached and then close the process. When you do "Find What Accesses" in Cheat Engine that will attach a debugger and if using default options will be detected by IsDebuggerPresent.
This can be hooked and patched, the next step is to manually check the BeingDebugged flag in the Process Environment Block
Get PEB pointer:
PEB* GetPEB()
{
#ifdef _WIN64
return (PEB*)__readgsword(0x60); //64 bit
#else
return (PEB*)__readfsdword(0x30); //32bit
#endif
}
Read the debugger flag:
bool IsDebugFlagSet(PEB* peb)
{
if (peb->BeingDebugged == 1) return true;
else return false;
}
If they're hooking IsDebuggerPresent() you can compare the bytes on disk to the bytes in memory at the beginning of the function and compare, or even easier just check the first byte and see if it's a relative jmp (x86 example)
Check for Hooks:
bool IsHooked(char* functionName, char* dllName)
{
BYTE* functionAddress = (BYTE*)GetProcAddress(GetModuleHandle(dllName), functionName);
return (*functionAddress == 0xE9);
}
Other tricks:
Hook LoadLibrary() & LDRLoadDLL() and stop them from loading rogue dlls
Scan running processes for memory editors by comparing the image name or image path using CreateToolHelp32Snapshot() against a blacklist
Fill all debug registers so debugger cannot be attached
Beyond these tricks you can use a commercial anticheat or kernel mode driver to protect your game, but the above tips will stop the average person.
Two ways to protect your data:
1) Only provide the user with binary files. Compiled code. Don't give them source code.
2) If your game is an online game, store sensitive data server side.
You should research an idea called "encapsulation" for use in designing APIs such that sensitive data is protected.

Changing Objective-C SDK settings from the application using it

I have a question regarding modifying SDK settings from the application using it.
I have a custom SDK which prints to a log when doing certain things. I want users of this SDK to be able to turn logging on/off. I use NSLog as my logger.
I have tried setting a preprocessor macro for this, as explained numerous times here in stackoverflow by doing something like:
#ifdef SHOWLOG
# define SLog(fmt, ...) NSLog((fmt), ##__VA_ARGS__);
#else
# define SLog(...)
#endif
And then expecting the user to set a compile flag called "-DSHOWLOG"
This does not work since the person who is using the SDK will have a compiled version of the SDK.
What other ways are there are there of changing configurations of SDK from the application that uses it?
Are environment variables a good option?
Maybe I'm misunderstanding the question, so I'll guess and offer this answer in the hope it helps:
Inside your SDK create your settings which you query to control how your SDK behaves. These settings can be stored in a shared/singleton object, behind a functional (i.e. C functions) API, or even just SDK (not publicly documented) global variables.
Provide a public API which alters the values of these settings.
So in the situation mentioned in the question you need an SDK-internal "show log" setting and a public API to set it.
HTH

For rebol3: Want to get started with native extensions on linux. How do I write a hello-world?

I know how to write some 100 lines C, but I do not know how to read/organize larger source like Rebol. Somewhere was a tutorial with hostkit and dll, but it seems R3 is now statically linked. So I do not know where to look.
How would I write a native which gets a value and returns another? Where to put it in the source? What to obey, like telling the GC I created something in C?
Also, how can I embed R3 in other programms, to call it from Python or Node? I ask for Python/Node part comes later. But my learning-main should access R3 in a similar way. Means dll. And are there some typical hooks for startup/shutdown etc in such ffi's?
[Edit: forgot to mention: it is for Rebol 3.]
That's two questions. :-)
Regarding the first (about adding a native)... it's probably best elaborated as developer documentation on a Wiki. Questions in the rebol tag should generally be more about the language from a user's point of view. The answers regarding source code itself typically will be long, and there's really only a few people who can answer it, or care about the answer (what StackOverflow calls "too localized"). And it will wind up being more of a c question at that point, if anything.
So telling the developers to get their act together and write that documentation and put it in a centrally organized place is probably the best idea! :-P But I actually did try this myself. I added a set-env native to set environment variables from the interpreter, and you can look at the diffs it took to do that in GitHub for a bit of an idea.
add SET-ENV, tweaks to host api for environment string handling
An important thing to remember is that when you touch certain files, you have to run make prep which does a lot of scanning and code generation automatically. Adding a native is one of those things where you're definitely going to have to do that, each time you change to an interface that fundamental.
As for your second question, which is more of a user-facing question about interpreter embedding, one of the first places to look is just in how the simple REPL is implemented. There are two versions in the main repository right now, one for Posix and one for Windows.
https://github.com/rebol/r3/blob/master/src/os/host-main.c
So a string goes in and a string comes out. But there are more complicated forms of interaction, and you can get to them from reb-host.h, which includes these files from src/include
#include "reb-config.h"
#include "reb-c.h"
#include "reb-ext.h" // includes reb-defs.h
#include "reb-args.h"
#include "reb-device.h"
#include "reb-file.h"
#include "reb-event.h"
#include "reb-evtypes.h"
#include "reb-net.h"
#include "reb-filereq.h"
#include "reb-gob.h"
#include "reb-lib.h"
So you can look through those files for the API as it existed at the moment of the December-12th open-sourcing. Things will be evolving, and hopefully much better documented. But for now that's what seems to be available. You could link the host kit as a shared/DLL or static library, it depends on your build settings and what compiler you use.

Getting LLVM/Clang to be 16 bit aligned

I am working on a legacy project that has a large amount of files dating back to pre-OS X days. It's data has been 16 bit aligned for > 15 years. I would like to move to a full LLVM compilation but I can't seem to get 2 byte alignment working. Are there any compiler level options available for this? (previously using -malign-mac68k)
I am aware of the #pragma pack(2) option here. However that would require me to modify upwards of 1000 source files to include this. That it's a worst-case option, but it seems like a hack. Besides, if this is possible then surely there is a default option to set the alignment?
According to clang's sources, it does support mac68k alignment rules. It seems that right now you can enable it via "#pragma options align=mac68k" only. If you're ok with small clang hacking, then you can implement the cmdline option as well and submit the patch to clang.
I would suggest looking at #pragma pack (see http://msdn.microsoft.com/en-us/library/2e70t5y1%28v=vs.80%29.aspx and http://gcc.gnu.org/onlinedocs/gcc/Structure_002dPacking-Pragmas.html). It's relatively easy to use, and should work with any compiler Apple ships.
i use the latest gcc/gortran on osx compiled by the guys at ibm, if you read the gcc manual there are at least 8 different alignment optimizations to consider not just the bulk malign
Because system-level headers assume default alignment (they don't have directives to override alignment in most cases), changing the alignment for everything will break OS calls. As such, you don't want to be doing this.
Just write a script to apply your #pragma pack(2) to the source files in question, avoiding #includes. It's relatively easy and unlikely to cause unfortunate side-effects.