Jump to content

[Dnlib, C#] - How to replace correctly the text of a string array ?


Doctor

Recommended Posts

The original of what should come out in the end.

public static string[] ss = new string[] 
{      
  "$DATA" // This line is replaced by the new
};

I want to get this result

public static string[] ss = new string[] 
{      
  ".data", ".txt", ".sfc", ".crypt"  
};

I use a textBox and enter data in the following format: .

.data .txt .sfc .crypt

I have a public dictionary where I put data

public static Dictionary<string, string> DicPairs = new Dictionary<string, string>

Adding data to the dictionary from a TextBox
 

string res = string.Join(", ", Enumerable.Select(textBox1.Text.Split()), s => $"\"{s}\""); // $"\"{s}\"" - To have brackets and comma between the text like ".data", ".txt" etc.
DicPairs.Add("MyText", res); // textBox1.Text

Search and change 
 

foreach (TypeDef types in module.GetTypes())
{
    foreach (MethodDef m in types.Methods)
    {
        var instr = m.Body.Instructions;
        for (var i = 0; i < m.Body.Instructions.Count; i++)
        {
             // string res = string.Join(", ", Enumerable.Select(DicPairs["MyText"].Split(), s => $"\"{s}\"");
              instr[i].Operand = DicPairs["MyText"]; // This is where my line is replaced
             //instr[i].Operand = string.Join(", ", Enumerable.Select(DicPairs["MyText"].Split(), s => $"\"{s}\""); // This is where my line is replaced
        }
     }
 }
...

But for some reason always when I open a file in DnSpy, I see the entries as these lines: 

 "\".data\", \".txt\", \".sfc\", \".crypt\""

How Fix ? 

Edited by Doctor
Link to comment

hey doc,

dont have VStudio version supporting interpolation but u can try this shit @ 

$@"\"{s}\""

docs.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated

  • Like 1
Link to comment

Your current approach isn't going to work, because you are treating the compiled binary as plain C# source code, where in fact it is not.

What you are doing right now, is replacing the single string $DATA with the single string ".data", ".txt", ".sfc", ".crypt", effectively creating a string array with just one element containing exactly your joined string. Your decompiler will then try to escape the string value since it contains quotation marks ("), rendering it as "\".data\", \".txt\", \".sfc\", \".crypt\"".

In CIL, string arrays are not stored as one string, but as multiple individual strings that you put into the array one-by-one. See https://sharplab.io/#v2:C4LglgNgNAJiDUAfAAgZgATIEzoMIQEMBnIgWACgBvC9WzDZARgDZNGAGAbQF10T0AvOgB2AUwDubLrxp1KdOrIUAiAHQwCwAsqjo1wAB7Ade1UQBmAYxNrLAJwCeAB2O0l6AL4BuCh6A===

Notice the pattern:

dup
ldc.i4 <index>
ldstr <string value>
stelem.ref

This is what you would need to reproduce for every element in your input collection.

Edited by Washi
  • Like 4
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...