1

I am trying to make a simple program to find some values in a file. These files are .arkprofile files and belong to the game ARK.

These .arkprofile files include some readable text as well as some scrambled text if you open it in a regular editor. All the values I need are in ASCII so I could get them all manually, but the intention of this program is to go through a lot of files to grab out the character names. Here is how it looks like in the file in a regular text editor:

PlayerCharacterName.....StrProperty.............CHARACTERNAMEHERE

Can I find this string without decompiling the file as hex first? Is it possible to convert the string to bytes and do the search from there?

This is the code I have at the moment, but it is not suited for my need as the hex offset for the string is not the same for all the files.

Dim pos1 As Long = 864

Dim requiredBytes As Integer = 160
Dim value(0 To requiredBytes - 1) As Byte
Using reader As New BinaryReader(File.Open(fd.FileName, FileMode.Open))
    ' Loop through length of file.
    Dim fileLength As Long = reader.BaseStream.Length
    Dim byteCount As Integer = 0
    reader.BaseStream.Seek(pos1, SeekOrigin.Begin)
    While pos1 < fileLength And byteCount < requiredBytes
        value(byteCount) = reader.ReadByte()
        pos1 += 1
        byteCount += 1
    End While
End Using

The dots between the strings change hex value from file to file, but its always the same amount of dots. Max character name allowed on ARK is 24, so my idea now was to first find that string in the file, start writing bytes from the end of that file for 128 bytes. "PlayerCharacterName.....StrProperty............." = 60 bytes. This is where the username would start and can be up to 24 characters long which is 48 bytes. Then I could filter out the remaining characters that are not a part of the username and display it in ASCII.

Am I way off track here?

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
  • If some of it is human-readable, then you can open the file as text and just find the string. – djv Oct 20 '16 at 17:13
  • Working on editing this post. New to this site and its setup! – Jaran Bjortomt Oct 20 '16 at 17:27
  • See my answer below – djv Oct 20 '16 at 17:27
  • When you say the character name uses ASCII characters, is that strictly true? Can you name a character, say, "ÛǾ▲" and see what appears in the text file? You might be better off looking at the text file in a hex editor so that you can be sure of how many bytes are used rather than whatever the text editor interprets characters as. – Andrew Morton Oct 20 '16 at 18:31

2 Answers2

0

Since you can read it in a text editor, you can just open it as a text file.

Imports System.IO

Module Module1

    Sub Main()
        Dim line As String = ""
        Using sr As New StreamReader("c:\temp\test.abc")
            While Not sr.EndOfStream
                line = sr.ReadLine()
                If line.StartsWith("PlayerCharacterName") Then
                    Exit While
                End If
            End While
        End Using
        If line = "" Then
            Console.WriteLine("Did not find the name!")
        Else
            Dim s = line.Split("."c)
            Dim name = s.Last()
            Console.WriteLine("Found name ""{0}""", name)
        End If
        Console.Read()
    End Sub

End Module

I put a file at c:\temp\test.abc to test. With this in it:

5tmodvVa640xaDv0fZ650R85uWo0R
CqwhYMD9e8h
FIEeAHhER6Qm2sWY38tKYO
i7diJRVGiZJUZHx26URbCwsewhby3NhPLMSMOv
w51Ft4I8aK2bjdu0OmzD3V5tDjlXnCXGfTk1NqAE
PlayerCharacterName.....StrProperty.............CHARACTERNAMEHERE
J4H73RcfdMVHkLIaXv
Yo5TCC6MmnkA51BZJcrCkzj62xucQ
8TR1QfSL1IRdmF2ScjjlokTHYHNa2suBk
1FBphwSK8aQWdfY1H9tKHSr
kLbQvNhUhILdcBv1EXXJgwZtQh37JZu2oXoHuCHRf2bpKsKmlZyf055Q5
ly0WxwtFP47BE0BAVD1sfWBogFR0Qb9r3DKBWiinRk9xLitqT
g5FgAyCQ5P7v3Z9hz04hQR1KU1SuoscYH7s5SYbHV1mJEnJKIb0

And this was the output of my program:

Found name "CHARACTERNAMEHERE"

djv
  • 15,168
  • 7
  • 48
  • 72
  • Thanks for your reply! I will play around a bit with the code to see if I can get it working. By running the code you posted I can see that it does find the string in the program, but it writes atotally diffrent value. I have tried to open the file as text in a textbox, but whatever I do end up with just a single scrabled character. Is there any specific way of doing this if the file is not a .txt file? – Jaran Bjortomt Oct 20 '16 at 18:04
  • Well in the end, a file is just a place on disk with *something* in it. Everything is saved as binary. It may be bits which represent some custom object, or bits which represent ASCII characters. You can open a binary file as text and see if the bits mean anything which is human readable. Seems like the devs of your game encoded the character names in there as text, which is good for your sake. I changed the answer to use a file called test.abc, and it still works. This shows there's nothing mystical about the .txt extension. It's all just binary data in the end. It's all about the encoding. – djv Oct 20 '16 at 18:22
  • 1
    @JaranBjortomt The dots appear to represent characters which the OP's text editor cannot display - maybe a regex split on [\x00-\x1F] would work. – Andrew Morton Oct 20 '16 at 18:37
  • Indeed, thats what I thought, but then again I don't get why I only get a single scrabeled character to show up in the textbox. Ill keep playing around with it. Thanks alot! – Jaran Bjortomt Oct 20 '16 at 18:38
  • If it's a binary file, is there any guarantee his key text is on it's own line? – Joel Coehoorn Oct 20 '16 at 19:11
  • No. I made this answer to get him in the right direction. He was stuck on the notion of reading the file as binary because of the "hex" representation he saw. Reading it again, he did not specify. – djv Oct 20 '16 at 19:53
0

This sounds like a job for a regular expression:

Public Function GetCharacterName(ByVal filePath As String) As String
    Dim exp As New RegEx("PlayerCharacterName.{5}StrProperty.{13}(.{1,24})")
    For Each line As String In File.ReadLines(filePath)
        Dim result = exp.Match(line)
        If result.Success Then
            Return result.Groups(1).Value
        End If
    Next line
    Return Nothing
End Function

My only concern with this is whether I built the expression correctly (I didn't have Visual Studio or real sample data handy) and whether some of the unprintable characters might produce an unexpected newline or multi-byte character.

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
  • Thanks alot to all of you! The code from @JoelCoehoorn seems to work exactly as I want it for most of the files. Some files turn up empty, but I belive im able to get it working. – Jaran Bjortomt Oct 20 '16 at 19:16
  • @JaranBjortomt You should examine the files where the result turns up empty with a hex editor to see what is different about them. At a pinch, you can use VS: [Can I hex edit a file in Visual Studio?](http://stackoverflow.com/a/1724591/1115360) – Andrew Morton Oct 20 '16 at 19:20
  • After looking over the files I can't see any connection. Out of 23 files, 20 works as intended and 3 turn out blank. http://download1488.mediafire.com/9act585kq3pg/4fq4s93jlgm5403/Overview.txt – Jaran Bjortomt Oct 20 '16 at 20:07
  • Messed up on the comment above. The link above is a textfile with the data I have collected and compared, but I can't see any issue. Filename and the actual character name to the left and the string and hex code to the right. Anyone else see an issue? – Jaran Bjortomt Oct 20 '16 at 20:10
  • How exactly does this "(.{1,24})" part of the regex work? Anything I have tried only ends in it grabbing 24 characters. Example: "Lego RawBoneModifier" – Jaran Bjortomt Oct 20 '16 at 23:00
  • The parentheses Mark the section to capture. {1,24} means take at least 1 character up to 24 that match the character class, and the period(.) means anything matches that character class, because there is no indication in the question how to know when the name ends. – Joel Coehoorn Oct 20 '16 at 23:20