[Samsung Galaxy S9  Guides, News, & Discussion] corsicanu:
Please take some time to read patiently everything. As always i`m not responsable for any damage that you do to your device.

Hello guys, i want to share some info with you. As recognised devs say from time to time, we just need to think outside the box, everything is there for us to read/learn. I`m gonna debate in this post 3 issues that i had and the workaround for them:

1. OMC code changing wants to wipe data..

But who will agree to that without a fair fight? I investigated the frameworks and found out that samsung sets country code to use from the mcc/mnc of the sim card inserted. Inside efs/imei should be a country code file named mps_code.dat, which it contains some code. Usually at the first boot framework is creating a new file in there named omcnw_code.dat containing sim card code.. After booting, it compares both files mps_code.dat and omcnw_code.dat and if the string inside doesn`t match, it prompts for a reboot to apply the country or reboot to factory reset to use new sim. Now, if you don`t have stock recovery to securely perform the wipe, you`ll probably end in bootloop. First time i ended in bootloop because of twrp, second time i mounted efs from twrp and manually changed the mps_code.dat according to sim country. Booted up and all just was ok, without the wipe that samsung added.

Therefore i tried to make a method inside SystemServer.smali (services.jar/smali/com/android/servers) that loads at boot, looks for the omcnw and if it`s found, it will delete mps_code.dat and rename omcnw_code.dat to mps_code.dat, so you won`t feel the change but also no more wipe prompt.

Under the # direct methods, anywhere after .method public constructor <init>()V i added this method:

.method private static deleteOmcnw()V
.locals 5

const-string/jumbo v2, "/efs/imei/omcnw_code.dat"

const-string/jumbo v3, "/efs/imei/mps_code.dat"

new-instance v0, Ljava/io/File;

invoke-direct {v0, v2}, Ljava/io/File;-><init>(Ljava/lang/String;)V

if-eqz v0, :cond_0

invoke-virtual {v0}, Ljava/io/File;->exists()Z

move-result v1

if-eqz v1, :cond_0

new-instance v1, Ljava/io/File;

invoke-direct {v1, v3}, Ljava/io/File;-><init>(Ljava/lang/String;)V

if-eqz v1, :cond_0

invoke-virtual {v1}, Ljava/io/File;->exists()Z

move-result v4

if-eqz v4, :cond_0

invoke-virtual {v1}, Ljava/io/File;->delete()Z

invoke-virtual {v0, v1}, Ljava/io/File;->renameTo(Ljava/io/File;)Z

:goto_0
return-void

:cond_0
const-string/jumbo v0, [COLOR="Blue"]"omcnw"[/COLOR]

const-string/jumbo v1, [COLOR="Blue"]"Some log lines, blah blah blah"[/COLOR]

invoke-static {v0, v1}, Lcom/android/server/utils/sysfwutil/Slog;->e(Ljava/lang/String;Ljava/lang/String;)I

goto :goto_0
.end method

And ofc now we need an invoke for this method.

I added it in .method private run()V after loading libandroid_servers

invoke-static {v0}, Landroid/os/Process;->setCanSelfBackground(Z)V

invoke-static {}, Landroid/os/Looper;->prepareMainLooper()V

const-string/jumbo v0, "android_servers"

invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V

[COLOR="Blue"]invoke-static {}, Lcom/android/server/SystemServer;->deleteOmcnw()V[/COLOR]

invoke-direct {p0}, Lcom/android/server/SystemServer;->performPendingShutdown()V

invoke-direct {p0}, Lcom/android/server/SystemServer;->createSystemContext()V

new-instance v0, Lcom/android/server/SystemServiceManager;

After this, no more prompt about wipe to use the sim.

2. OMC is a pain when it comes to add features..

I wanted to add csc features but either omc was encrypted (which has a solution now), or either way too many xmls to edit.. Investigated a bit SemCscFeature.smali (framework.jar/smali_classes3/samsung/android/feature) and gave me an idea that actually worked.

The point was to duplicate loadNetworkFeatureFile method, rename it, point it to certain location where we will add a single xml file containing all the features we want and add the invoke right after loadNetworkFeatureFile invoke. By doing this, doesn`t matter what csc is loaded, the system will load our custom xml too. Less time to add features, cleaner way to load, and it doesn`t even need to decrypt omc. And by using a duplicate of loadNetworkFeatureFile we can encrypt our xml too :) .

I`m gonna post my methods too, might be a bit sloppy code, i lost myself inside of it, but as long as it does what it`s supposed, doesn`t matter anymore :laugh:

Gonna hide the method as it is a long one

.method private loadHadesFeatureFile(ZLjava/lang/String;)V
.locals 24

const/16 v16, 0x0

const/4 v12, 0x0

const/4 v14, 0x0

const/4 v7, -0x1

const/4 v2, 0x0

const/4 v3, 0x0

const/4 v10, 0x0

[COLOR="Blue"]const-string/jumbo v10, "/system/etc" # custom xml path here[/COLOR]

:try_start_0
new-instance v11, Ljava/io/File;

new-instance v20, Ljava/lang/StringBuilder;

invoke-direct/range {v20 .. v20}, Ljava/lang/StringBuilder;-><init>()V

move-object/from16 v0, v20

invoke-virtual {v0, v10}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

move-result-object v20

[COLOR="Blue"]const-string/jumbo v21, "/hades.xml" # custom xml name here[/COLOR]

invoke-virtual/range {v20 .. v21}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

move-result-object v20

invoke-virtual/range {v20 .. v20}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

move-result-object v20

move-object/from16 v0, v20

invoke-direct {v11, v0}, Ljava/io/File;-><init>(Ljava/lang/String;)V

invoke-virtual {v11}, Ljava/io/File;->exists()Z

move-result v20

if-eqz v20, :cond_0

invoke-virtual {v11}, Ljava/io/File;->length()J

move-result-wide v20

const-wide/16 v22, 0x0

cmp-long v20, v20, v22

if-gtz v20, :cond_1

:cond_0
return-void

:cond_1
invoke-static {}, Lorg/xmlpull/v1/XmlPullParserFactory;->newInstance()Lorg/xmlpull/v1/XmlPullParserFactory;

move-result-object v9

const/16 v20, 0x1

move/from16 v0, v20

invoke-virtual {v9, v0}, Lorg/xmlpull/v1/XmlPullParserFactory;->setNamespaceAware(Z)V

invoke-virtual {v9}, Lorg/xmlpull/v1/XmlPullParserFactory;->newPullParser()Lorg/xmlpull/v1/XmlPullParser;

move-result-object v16

new-instance v13, Ljava/io/FileInputStream;

invoke-direct {v13, v11}, Ljava/io/FileInputStream;-><init>(Ljava/io/File;)V
:try_end_0
.catch Lorg/xmlpull/v1/XmlPullParserException; {:try_start_0 .. :try_end_0} :catch_b
.catch Ljava/io/FileNotFoundException; {:try_start_0 .. :try_end_0} :catch_d
.catch Ljava/io/IOException; {:try_start_0 .. :try_end_0} :catch_f
.catchall {:try_start_0 .. :try_end_0} :catchall_1

:try_start_1
move-object/from16 v0, p0

invoke-direct {v0, v11}, Lcom/samsung/android/feature/SemCscFeature;->isXmlEncoded(Ljava/io/File;)Z

move-result v20

if-eqz v20, :cond_3

invoke-virtual {v13}, Ljava/io/FileInputStream;->available()I

move-result v18

move/from16 v0, v18

new-array v0, v0, [B

move-object/from16 v19, v0

move-object/from16 v0, v19

invoke-virtual {v13, v0}, Ljava/io/FileInputStream;->read([B)I

invoke-virtual {v13}, Ljava/io/FileInputStream;->close()V

move-object/from16 v0, p0

move-object/from16 v1, v19

invoke-direct {v0, v1}, Lcom/samsung/android/feature/SemCscFeature;->decode([B)[B

move-result-object v17

new-instance v15, Ljava/io/ByteArrayInputStream;

move-object/from16 v0, v17

invoke-direct {v15, v0}, Ljava/io/ByteArrayInputStream;-><init>([B)V
:try_end_1
.catch Lorg/xmlpull/v1/XmlPullParserException; {:try_start_1 .. :try_end_1} :catch_0
.catch Ljava/io/FileNotFoundException; {:try_start_1 .. :try_end_1} :catch_2
.catch Ljava/io/IOException; {:try_start_1 .. :try_end_1} :catch_5
.catchall {:try_start_1 .. :try_end_1} :catchall_0

const/16 v20, 0x0

:try_start_2
move-object/from16 v0, v16

move-object/from16 v1, v20

invoke-interface {v0, v15, v1}, Lorg/xmlpull/v1/XmlPullParser;->setInput(Ljava/io/InputStream;Ljava/lang/String;)V
:try_end_2
.catch Lorg/xmlpull/v1/XmlPullParserException; {:try_start_2 .. :try_end_2} :catch_c
.catch Ljava/io/FileNotFoundException; {:try_start_2 .. :try_end_2} :catch_e
.catch Ljava/io/IOException; {:try_start_2 .. :try_end_2} :catch_10
.catchall {:try_start_2 .. :try_end_2} :catchall_2

move-object v14, v15

:goto_0
:try_start_3
invoke-interface/range {v16 .. v16}, Lorg/xmlpull/v1/XmlPullParser;->getEventType()I

move-result v7

:goto_1
const/16 v20, 0x1

move/from16 v0, v20

if-eq v7, v0, :cond_c

const/16 v20, 0x2

move/from16 v0, v20

if-ne v7, v0, :cond_6

invoke-interface/range {v16 .. v16}, Lorg/xmlpull/v1/XmlPullParser;->getName()Ljava/lang/String;
:try_end_3
.catch Lorg/xmlpull/v1/XmlPullParserException; {:try_start_3 .. :try_end_3} :catch_0
.catch Ljava/io/FileNotFoundException; {:try_start_3 .. :try_end_3} :catch_2
.catch Ljava/io/IOException; {:try_start_3 .. :try_end_3} :catch_5
.catchall {:try_start_3 .. :try_end_3} :catchall_0

move-result-object v2

:cond_2
:goto_2
:try_start_4
invoke-interface/range {v16 .. v16}, Lorg/xmlpull/v1/XmlPullParser;->next()I
:try_end_4
.catch Ljava/io/IOException; {:try_start_4 .. :try_end_4} :catch_7
.catch Lorg/xmlpull/v1/XmlPullParserException; {:try_start_4 .. :try_end_4} :catch_0
.catch Ljava/io/FileNotFoundException; {:try_start_4 .. :try_end_4} :catch_2
.catchall {:try_start_4 .. :try_end_4} :catchall_0

move-result v7

goto :goto_1

:cond_3
const/16 v20, 0x0

:try_start_5
move-object/from16 v0, v16

move-object/from16 v1, v20

invoke-interface {v0, v13, v1}, Lorg/xmlpull/v1/XmlPullParser;->setInput(Ljava/io/InputStream;Ljava/lang/String;)V
:try_end_5
.catch Lorg/xmlpull/v1/XmlPullParserException; {:try_start_5 .. :try_end_5} :catch_0
.catch Ljava/io/FileNotFoundException; {:try_start_5 .. :try_end_5} :catch_2
.catch Ljava/io/IOException; {:try_start_5 .. :try_end_5} :catch_5
.catchall {:try_start_5 .. :try_end_5} :catchall_0

goto :goto_0

:catch_0
move-exception v6

move-object v12, v13

:goto_3
:try_start_6
const-string/jumbo v20, "SemCscFeature"

invoke-virtual {v6}, Ljava/lang/Throwable;->toString()Ljava/lang/String;

move-result-object v21

invoke-static/range {v20 .. v21}, Landroid/util/Log;->w(Ljava/lang/String;Ljava/lang/String;)I
:try_end_6
.catchall {:try_start_6 .. :try_end_6} :catchall_1

if-eqz v12, :cond_4

:try_start_7
invoke-virtual {v12}, Ljava/io/FileInputStream;->close()V

const/4 v12, 0x0

:cond_4
if-eqz v14, :cond_5

invoke-virtual {v14}, Ljava/io/ByteArrayInputStream;->close()V
:try_end_7
.catch Ljava/io/IOException; {:try_start_7 .. :try_end_7} :catch_9

:goto_4
const/4 v14, 0x0

:cond_5
:goto_5
return-void

:cond_6
const/16 v20, 0x4

move/from16 v0, v20

if-ne v7, v0, :cond_2

:try_start_8
invoke-interface/range {v16 .. v16}, Lorg/xmlpull/v1/XmlPullParser;->getText()Ljava/lang/String;

move-result-object v3

if-eqz v2, :cond_2

if-eqz v3, :cond_2

move-object/from16 v0, p0

iget-object v0, v0, Lcom/samsung/android/feature/SemCscFeature;->mFeatureList:Ljava/util/Hashtable;

move-object/from16 v20, v0

move-object/from16 v0, v20

invoke-virtual {v0, v2}, Ljava/util/Hashtable;->containsKey(Ljava/lang/Object;)Z
:try_end_8
.catch Lorg/xmlpull/v1/XmlPullParserException; {:try_start_8 .. :try_end_8} :catch_0
.catch Ljava/io/FileNotFoundException; {:try_start_8 .. :try_end_8} :catch_2
.catch Ljava/io/IOException; {:try_start_8 .. :try_end_8} :catch_5
.catchall {:try_start_8 .. :try_end_8} :catchall_0

move-result v20

if-eqz v20, :cond_8

:try_start_9
invoke-interface/range {v16 .. v16}, Lorg/xmlpull/v1/XmlPullParser;->next()I
:try_end_9
.catch Ljava/io/IOException; {:try_start_9 .. :try_end_9} :catch_1
.catch Lorg/xmlpull/v1/XmlPullParserException; {:try_start_9 .. :try_end_9} :catch_0
.catch Ljava/io/FileNotFoundException; {:try_start_9 .. :try_end_9} :catch_2
.catchall {:try_start_9 .. :try_end_9} :catchall_0

move-result v7

goto :goto_1

:catch_1
move-exception v5

:try_start_a
const-string/jumbo v20, "SemCscFeature"

invoke-virtual {v5}, Ljava/lang/Throwable;->toString()Ljava/lang/String;

move-result-object v21

invoke-static/range {v20 .. v21}, Landroid/util/Log;->w(Ljava/lang/String;Ljava/lang/String;)I
:try_end_a
.catch Lorg/xmlpull/v1/XmlPullParserException; {:try_start_a .. :try_end_a} :catch_0
.catch Ljava/io/FileNotFoundException; {:try_start_a .. :try_end_a} :catch_2
.catch Ljava/io/IOException; {:try_start_a .. :try_end_a} :catch_5
.catchall {:try_start_a .. :try_end_a} :catchall_0

goto :goto_1

:catch_2
move-exception v4

move-object v12, v13

:goto_6
:try_start_b
const-string/jumbo v20, "SemCscFeature"

invoke-virtual {v4}, Ljava/lang/Throwable;->toString()Ljava/lang/String;

move-result-object v21

invoke-static/range {v20 .. v21}, Landroid/util/Log;->w(Ljava/lang/String;Ljava/lang/String;)I
:try_end_b
.catchall {:try_start_b .. :try_end_b} :catchall_1

if-eqz v12, :cond_7

:try_start_c
invoke-virtual {v12}, Ljava/io/FileInputStream;->close()V

const/4 v12, 0x0

:cond_7
if-eqz v14, :cond_5

invoke-virtual {v14}, Ljava/io/ByteArrayInputStream;->close()V
:try_end_c
.catch Ljava/io/IOException; {:try_start_c .. :try_end_c} :catch_3

goto :goto_4

:catch_3
move-exception v5

const-string/jumbo v20, "SemCscFeature"

invoke-virtual {v5}, Ljava/lang/Throwable;->toString()Ljava/lang/String;

move-result-object v21

invoke-static/range {v20 .. v21}, Landroid/util/Log;->w(Ljava/lang/String;Ljava/lang/String;)I

goto :goto_5

:cond_8
:try_start_d
invoke-virtual {v3}, Ljava/lang/String;->trim()Ljava/lang/String;

move-result-object v3

move-object/from16 v0, p0

iget-object v0, v0, Lcom/samsung/android/feature/SemCscFeature;->mFeatureList:Ljava/util/Hashtable;

move-object/from16 v20, v0

move-object/from16 v0, v20

invoke-virtual {v0, v2, v3}, Ljava/util/Hashtable;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
:try_end_d
.catch Ljava/lang/Exception; {:try_start_d .. :try_end_d} :catch_4
.catch Lorg/xmlpull/v1/XmlPullParserException; {:try_start_d .. :try_end_d} :catch_0
.catch Ljava/io/FileNotFoundException; {:try_start_d .. :try_end_d} :catch_2
.catch Ljava/io/IOException; {:try_start_d .. :try_end_d} :catch_5
.catchall {:try_start_d .. :try_end_d} :catchall_0

goto/16 :goto_2

:catch_4
move-exception v8

:try_start_e
const-string/jumbo v20, "SemCscFeature"

invoke-virtual {v8}, Ljava/lang/Throwable;->toString()Ljava/lang/String;

move-result-object v21

invoke-static/range {v20 .. v21}, Landroid/util/Log;->w(Ljava/lang/String;Ljava/lang/String;)I
:try_end_e
.catch Lorg/xmlpull/v1/XmlPullParserException; {:try_start_e .. :try_end_e} :catch_0
.catch Ljava/io/FileNotFoundException; {:try_start_e .. :try_end_e} :catch_2
.catch Ljava/io/IOException; {:try_start_e .. :try_end_e} :catch_5
.catchall {:try_start_e .. :try_end_e} :catchall_0

goto/16 :goto_2

:catch_5
move-exception v5

move-object v12, v13

:goto_7
:try_start_f
const-string/jumbo v20, "SemCscFeature"

invoke-virtual {v5}, Ljava/lang/Throwable;->toString()Ljava/lang/String;

move-result-object v21

invoke-static/range {v20 .. v21}, Landroid/util/Log;->w(Ljava/lang/String;Ljava/lang/String;)I
:try_end_f
.catchall {:try_start_f .. :try_end_f} :catchall_1

if-eqz v12, :cond_9

:try_start_10
invoke-virtual {v12}, Ljava/io/FileInputStream;->close()V

const/4 v12, 0x0

:cond_9
if-eqz v14, :cond_5

invoke-virtual {v14}, Ljava/io/ByteArrayInputStream;->close()V
:try_end_10
.catch Ljava/io/IOException; {:try_start_10 .. :try_end_10} :catch_6

goto/16 :goto_4

:catch_6
move-exception v5

const-string/jumbo v20, "SemCscFeature"

invoke-virtual {v5}, Ljava/lang/Throwable;->toString()Ljava/lang/String;

move-result-object v21

invoke-static/range {v20 .. v21}, Landroid/util/Log;->w(Ljava/lang/String;Ljava/lang/String;)I

goto/16 :goto_5

:catch_7
move-exception v5

:try_start_11
const-string/jumbo v20, "SemCscFeature"

invoke-virtual {v5}, Ljava/lang/Throwable;->toString()Ljava/lang/String;

move-result-object v21

invoke-static/range {v20 .. v21}, Landroid/util/Log;->w(Ljava/lang/String;Ljava/lang/String;)I
:try_end_11
.catch Lorg/xmlpull/v1/XmlPullParserException; {:try_start_11 .. :try_end_11} :catch_0
.catch Ljava/io/FileNotFoundException; {:try_start_11 .. :try_end_11} :catch_2
.catch Ljava/io/IOException; {:try_start_11 .. :try_end_11} :catch_5
.catchall {:try_start_11 .. :try_end_11} :catchall_0

goto/16 :goto_1

:catchall_0
move-exception v20

move-object v12, v13

:goto_8
if-eqz v12, :cond_a

:try_start_12
invoke-virtual {v12}, Ljava/io/FileInputStream;->close()V

const/4 v12, 0x0

:cond_a
if-eqz v14, :cond_b

invoke-virtual {v14}, Ljava/io/ByteArrayInputStream;->close()V
:try_end_12
.catch Ljava/io/IOException; {:try_start_12 .. :try_end_12} :catch_a

const/4 v14, 0x0

:cond_b
:goto_9
throw v20

:cond_c
if-eqz v13, :cond_d

:try_start_13
invoke-virtual {v13}, Ljava/io/FileInputStream;->close()V
:try_end_13
.catch Ljava/io/IOException; {:try_start_13 .. :try_end_13} :catch_11

const/4 v12, 0x0

:goto_a
if-eqz v14, :cond_5

:try_start_14
invoke-virtual {v14}, Ljava/io/ByteArrayInputStream;->close()V
:try_end_14
.catch Ljava/io/IOException; {:try_start_14 .. :try_end_14} :catch_8

goto/16 :goto_4

:catch_8
move-exception v5

:goto_b
const-string/jumbo v20, "SemCscFeature"

invoke-virtual {v5}, Ljava/lang/Throwable;->toString()Ljava/lang/String;

move-result-object v21

invoke-static/range {v20 .. v21}, Landroid/util/Log;->w(Ljava/lang/String;Ljava/lang/String;)I

goto/16 :goto_5

:catch_9
move-exception v5

const-string/jumbo v20, "SemCscFeature"

invoke-virtual {v5}, Ljava/lang/Throwable;->toString()Ljava/lang/String;

move-result-object v21

invoke-static/range {v20 .. v21}, Landroid/util/Log;->w(Ljava/lang/String;Ljava/lang/String;)I

goto/16 :goto_5

:catch_a
move-exception v5

const-string/jumbo v21, "SemCscFeature"

invoke-virtual {v5}, Ljava/lang/Throwable;->toString()Ljava/lang/String;

move-result-object v22

invoke-static/range {v21 .. v22}, Landroid/util/Log;->w(Ljava/lang/String;Ljava/lang/String;)I

goto :goto_9

:catchall_1
move-exception v20

goto :goto_8

:catchall_2
move-exception v20

move-object v14, v15

move-object v12, v13

goto :goto_8

:catch_b
move-exception v6

goto/16 :goto_3

:catch_c
move-exception v6

move-object v14, v15

move-object v12, v13

goto/16 :goto_3

:catch_d
move-exception v4

goto/16 :goto_6

:catch_e
move-exception v4

move-object v14, v15

move-object v12, v13

goto/16 :goto_6

:catch_f
move-exception v5

goto/16 :goto_7

:catch_10
move-exception v5

move-object v14, v15

move-object v12, v13

goto/16 :goto_7

:catch_11
move-exception v5

move-object v12, v13

goto :goto_b

:cond_d
move-object v12, v13

goto :goto_a
.end method

And the invoke:

...

invoke-direct {p0, v2, v4}, Lcom/samsung/android/feature/SemCscFeature;->loadFeatureFile(ZLjava/lang/String;)Z

move-result v5

if-eqz v5, :cond_1

invoke-direct {p0, v2, v3}, Lcom/samsung/android/feature/SemCscFeature;->loadNetworkFeatureFile(ZLjava/lang/String;)V

[COLOR="Blue"]invoke-direct {p0, v2, v3}, Lcom/samsung/android/feature/SemCscFeature;->loadHadesFeatureFile(ZLjava/lang/String;)V[/COLOR]
:try_end_0
.catch Ljava/lang/Exception; {:try_start_0 .. :try_end_0} :catch_0

...

The code can be simplified, i didn`t bothered to do that, feel free to manipulate it in which way you want.

3. Use ODM instead of OMC/CSC in Oreo

From S9 Samsung introduced a new kind of omc, ODM, which needs its own partition and needs to be loaded from fstab/dts. We can add it to non ODM devices with a pretty simple and clean workaround.

Inside ramdisk, in init.rc file (all the devices should have that), i found this:

# Link /vendor to /system/vendor for devices without a vendor partition.
symlink /system/vendor /vendor

Following this we can make it work just like this:

# Link /vendor to /system/vendor for devices without a vendor partition.
symlink /system/vendor /vendor
[color="Blue"] symlink /system/odm /odm[/color]

By unpacking odm partition content inside a folder from system and creating the symlink from above at boot, rom will load odm as it has the partition.

Hope these tips will help someone in the future of custom roms with more features.

I will attach to this thread my modified smalis from one of my roms, i tried these methods on 7.1.1, but the idea is the same for oreo too, code might be slighlty different.

All the best :fingers-crossed: