[GUIDE][Dev-Only] OMC/ODM manipulation tips and tricks

Search This thread

corsicanu

Recognized Developer
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:
Code:
.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
Code:
    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
Code:
.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:
Code:
...

    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:
Code:
    # 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:
Code:
    # 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:
 

Attachments

  • smalis.zip
    36.8 KB · Views: 330
Last edited:

_alexndr

Senior Member
Mar 1, 2013
2,850
17,956
Samsung Galaxy S23 Ultra
Interesting thoughts :good: Thanks

I am not an opponent of your method - I just wanted to show another possibility which does not require "touching" framework to achieve goal, maybe it will be helpful for someone :cool:

Personally I prefer to do the job by the installer. My installer matches all entries in files in /efs/imei automatically during install. Also - it matches last 3 characters in prodcode.dat to current or new (forced) CSC :cowboy:

Example from my DevBase (where $1 - CSC to set or match, $2 (optional - temporary location with new omc content extracted from sec_omc.zip or only just unencrypted XMLs to replace)

Code:
set_csc() {
    local NV_MPS=
    local NV_OMC=
    local NV_OMC2=
    local UMOUNT=false
    local OMC=/odm/omc
    if [ -z "$1" ] ; then return ; fi
    if [ ! -d $OMC ] ; then OMC=/system/omc ; fi
    if [ -d $2$OMC ] ; then
        # modify /efs only if there is no other way
        if (! is_mounted /efs) ; then
            mkdir -p /efs
            mount -t ext4 $EFS /efs
            UMOUNT=true
        elif (! is_mounted /efs rw) ; then
            mount -o rw,remount /efs
        fi
        NV_MPS=$(cat /efs/imei/mps_code.dat)
        NV_OMC=$(cat /efs/imei/omcnw_code.dat)
        NV_OMC2=$(cat /efs/imei/omcnw_code2.dat)
        if [ ! -z "$NV_MPS" ] && [ "$NV_MPS" != "$1" ] ; then
            sed -i "s/$NV_MPS/$1/g" /efs/imei/mps_code.dat
            cat /efs/imei/prodcode.dat 2>/dev/null | grep "$NV_MPS$" >/dev/null && sed -i "s/$NV_MPS$/$1/g" /efs/imei/prodcode.dat
        fi
        if [ ! -z "$NV_OMC" ] && [ "$NV_OMC" != "$1" ] ; then
            sed -i "s/$NV_OMC/$1/g" /efs/imei/omcnw_code.dat
            cat /efs/imei/prodcode.dat 2>/dev/null | grep "$NV_OMC$" >/dev/null && sed -i "s/$NV_OMC$/$1/g" /efs/imei/prodcode.dat
        fi
        if [ ! -z "$NV_OMC2" ] && [ "$NV_OMC2" != "$1" ] ; then
            sed -i "s/$NV_OMC2/$1/g" /efs/imei/omcnw_code2.dat
            cat /efs/imei/prodcode.dat 2>/dev/null | grep "$NV_OMC2$" >/dev/null && sed -i "s/$NV_OMC2$/$1/g" /efs/imei/prodcode.dat
        fi
        sync
        ($UMOUNT) && umount /efs
        if [ ! -z "$2" ] ; then
            find $2/odm -type f ! -name cscfeature*.xml -delete # replace only encrypted XMLs in /odm/omc
            mkdir $OMC && set_perm 0 0 751 $OMC
            set_perm_rec 0 0 755 644 $2$OMC
            cp -af $2$OMC/* $OMC
            rm -Rf $2
        fi
        # cosmetic action, the file below does not really matter
        echo $1 > $OMC/sales_code.dat
        set_perm 0 0 644 $OMC/sales_code.dat
    elif [ -d $2/system/csc ] ; then
        if [ ! -z "$2" ] ; then
            set_perm_rec 0 0 755 644 $2/system
            cp -af $2/system/* /system
            rm -Rf $2
        fi
        cp -af /system/csc/common/system/* /system
        cp -af /system/csc/$1/system/* /system
        ln -sf /system/csc/$1/csc_contents /system/csc_contents
    else
        return 1
    fi
    return 0
}

Above works in N8 and also in S9(+) where CSC path has been changed to /odm/omc

[...]
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.. [...]

In point 2 you showed really interesting alternative of editing cscfeature.xml, but I do not agree that it is a pain because we need to edit "many xmls".

It is enough to edit only one file on the fly by the installer, depending on device it is /system/omc/{current_csc}/cscfeature.xml or /odm/omc/{current_csc}/conf/cscfeature.xml

Anyway, the advantage of your method is that we do not need to touch original CSC content at all, so I think many Devs will prefer your way :good:
 
Last edited:

corsicanu

Recognized Developer
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:
Code:
    # 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:
Code:
    # 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.
Updated first post as well :fingers-crossed:
 

Giorgatzelos

Senior Member
Dec 10, 2017
69
29
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:
Code:
.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
Code:
    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
Code:
.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:
Code:
...

    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:
Code:
    # 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:
Code:
    # 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:

I believe this thread needs to be updated...????i followed your guide in oreo and i try to find the second smali SemCscFeature.smali (framework.jar/smali_classes3/samsung/android/feature)*but i dont seem to find it in framework.jar and smali_classes3/.....path you mentioned above.?
 

louforgiveno

Senior Member
Jun 24, 2010
3,973
2,509
I believe this thread needs to be updated...????i followed your guide in oreo and i try to find the second smali SemCscFeature.smali (framework.jar/smali_classes3/samsung/android/feature)*but i dont seem to find it in framework.jar and smali_classes3/.....path you mentioned above.?
Lol, I think your post needs to be updated!!
You quoted the OP......wow, scrolling for days.

Sent from my God Mode 8
 

mojo_ojoj

Senior Member
Apr 21, 2012
66
3
OnePlus 8T
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:
Code:
    # 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:
Code:
    # 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.[/QUOTE]


Hi,

How I'm a noob and having a problem flashing stock rom or custom rom using Odin... I'm getting the error Failed to mount /odm (invalid argument). Will this help the problem? if yes, can you give me a step by step instruction on how to fix the odm. How do you unpack the odm partition content?


I'm sorry... I didn't read the header. Just ignore my message. I'm just so desperarate on fixing the "failed to mount /odm (inavlid argument). I'm really sorry!

Thank you nwei.
 
Last edited:

tokafondo

Senior Member
Jun 3, 2010
117
29
Samsung Galaxy S9+
I flashed twrp and mounted odm parition there.

I modified /odm/etc/omc/PHE/conf/cscfeature.xml and /odm/etc/omc/PHE/etc/contents.db files and the filesystem didn't complain about being read only.

I double checked that the files were indeed saved as the ones I modified.

I rebooted to normal and...

those files as original.

Was odm falsely modified?
 

Top Liked Posts

  • There are no posts matching your filters.
  • 29
    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:
    Code:
    .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
    Code:
        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
    Code:
    .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:
    Code:
    ...
    
        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:
    Code:
        # 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:
    Code:
        # 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:
    6
    Interesting thoughts :good: Thanks

    I am not an opponent of your method - I just wanted to show another possibility which does not require "touching" framework to achieve goal, maybe it will be helpful for someone :cool:

    Personally I prefer to do the job by the installer. My installer matches all entries in files in /efs/imei automatically during install. Also - it matches last 3 characters in prodcode.dat to current or new (forced) CSC :cowboy:

    Example from my DevBase (where $1 - CSC to set or match, $2 (optional - temporary location with new omc content extracted from sec_omc.zip or only just unencrypted XMLs to replace)

    Code:
    set_csc() {
        local NV_MPS=
        local NV_OMC=
        local NV_OMC2=
        local UMOUNT=false
        local OMC=/odm/omc
        if [ -z "$1" ] ; then return ; fi
        if [ ! -d $OMC ] ; then OMC=/system/omc ; fi
        if [ -d $2$OMC ] ; then
            # modify /efs only if there is no other way
            if (! is_mounted /efs) ; then
                mkdir -p /efs
                mount -t ext4 $EFS /efs
                UMOUNT=true
            elif (! is_mounted /efs rw) ; then
                mount -o rw,remount /efs
            fi
            NV_MPS=$(cat /efs/imei/mps_code.dat)
            NV_OMC=$(cat /efs/imei/omcnw_code.dat)
            NV_OMC2=$(cat /efs/imei/omcnw_code2.dat)
            if [ ! -z "$NV_MPS" ] && [ "$NV_MPS" != "$1" ] ; then
                sed -i "s/$NV_MPS/$1/g" /efs/imei/mps_code.dat
                cat /efs/imei/prodcode.dat 2>/dev/null | grep "$NV_MPS$" >/dev/null && sed -i "s/$NV_MPS$/$1/g" /efs/imei/prodcode.dat
            fi
            if [ ! -z "$NV_OMC" ] && [ "$NV_OMC" != "$1" ] ; then
                sed -i "s/$NV_OMC/$1/g" /efs/imei/omcnw_code.dat
                cat /efs/imei/prodcode.dat 2>/dev/null | grep "$NV_OMC$" >/dev/null && sed -i "s/$NV_OMC$/$1/g" /efs/imei/prodcode.dat
            fi
            if [ ! -z "$NV_OMC2" ] && [ "$NV_OMC2" != "$1" ] ; then
                sed -i "s/$NV_OMC2/$1/g" /efs/imei/omcnw_code2.dat
                cat /efs/imei/prodcode.dat 2>/dev/null | grep "$NV_OMC2$" >/dev/null && sed -i "s/$NV_OMC2$/$1/g" /efs/imei/prodcode.dat
            fi
            sync
            ($UMOUNT) && umount /efs
            if [ ! -z "$2" ] ; then
                find $2/odm -type f ! -name cscfeature*.xml -delete # replace only encrypted XMLs in /odm/omc
                mkdir $OMC && set_perm 0 0 751 $OMC
                set_perm_rec 0 0 755 644 $2$OMC
                cp -af $2$OMC/* $OMC
                rm -Rf $2
            fi
            # cosmetic action, the file below does not really matter
            echo $1 > $OMC/sales_code.dat
            set_perm 0 0 644 $OMC/sales_code.dat
        elif [ -d $2/system/csc ] ; then
            if [ ! -z "$2" ] ; then
                set_perm_rec 0 0 755 644 $2/system
                cp -af $2/system/* /system
                rm -Rf $2
            fi
            cp -af /system/csc/common/system/* /system
            cp -af /system/csc/$1/system/* /system
            ln -sf /system/csc/$1/csc_contents /system/csc_contents
        else
            return 1
        fi
        return 0
    }

    Above works in N8 and also in S9(+) where CSC path has been changed to /odm/omc

    [...]
    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.. [...]

    In point 2 you showed really interesting alternative of editing cscfeature.xml, but I do not agree that it is a pain because we need to edit "many xmls".

    It is enough to edit only one file on the fly by the installer, depending on device it is /system/omc/{current_csc}/cscfeature.xml or /odm/omc/{current_csc}/conf/cscfeature.xml

    Anyway, the advantage of your method is that we do not need to touch original CSC content at all, so I think many Devs will prefer your way :good:
    4
    Nice you decided to share this. Hope csc mod for devs will be easier now ;)
    2
    Nice work, but I prefer to use xposed to hook these methods.
    1
    :D:D:D Thanx...:D
    I still didnt find an answer to my question though..:eek:
    Sorry, i'm still on Nougat....but in the past when i've followed guides and not found entry in the said path, i've sometimes found it in other paths.

    Sent from my God Mode 8