解码二进制 - 基础知识

逆向工程 二元分析 十六进制 二进制
2021-07-07 09:39:31

我正在尝试解码这个来自缓存的二进制文件。我想要的只是播放列表元数据。我使用简单的十六进制查看器获取了其中的一些信息,但大部分信息是随机的 ascii。这是因为没有考虑到一些偏移吗?或者是否有更复杂的事情发生,例如散列或加密?

2个回答

使用010 Editor转换为二进制,使用Strings提取字符串,并使用Notepad++使用一些巧妙的正则表达式来删除一些明显的坏字符串。结果如下。

free
premium
shuffle
all
commercial
everywhere
Fetty Wap
Wiz Khalifa
SKE
Charlie Puth
T-Wayne
Major Lazer
DJ Snake
DJ Snake
Jason Derulo
Jack 
Skrillex
Cbc
Diplo
Justin Bieber
Walk the Moon
The Weeknd
Flo Rida
Sage The Gemini
Lookasx
Mark Ronson
Bruno Mars
Sna
David Guetta
Afrojack
Nicki Minaj
Ellie Goulding
Srl
Various Artistsx
Rihanna
Natalie La Rose
Jeremih
Ed Sheeran
Tove Lo
Drake
Fifth Harmony
Kid Ink
XMS
Omarion
Chris Brown
AlunaGeorge
OMI
Pitbull
Parson James
Andy Grammer
Kanye West
Paul McCartney
Hozier
doon
Lil Wayne
Meghan Trainor
Ariana Grande
Usher
Juicy J
Sam Smith
John Legend
Zedd
Selena Gomez
Rae Sremmurd
Young Thug
Big Sean
Trey Songz
AAC
Fall Out Boy
Theophilus London
Allan Kingdom
Kendrick Lamar
Sia
Deorro
Vance Joy
Trap Queen
Nasty Freestyle
Peace Is The Mission
Want To Want Me
TALKING IS HARD
MY HOUSE
Uptown Special
Love Me Like You Do
YAP
Bitch Better Have My Money
Bitch Better Have My Money
Somebody
Queen Of The Clouds
Queen Of The Clouds
Sex Playlist
You Know You Like It
You Know You Like It
Cheerleader
Globalization
Stole the Show
Magazines Or Novels
FourFiveSeconds
FourFiveSeconds
AAJ
Hozier
Truffle Butter
Lay Me Down
I Want You To Know
I Want You To Know
SremmLife
Dark Sky Paradise
Slow Motion
All Day
To Pimp A Butterfly
In The Lonely Hour
American Oxygen
American Oxygen
Five More Hours
Dream Your Life Away
Trap Queen
Nasty Freestyle
Want To Want Me
Shut Up and Dance
Uptown Funk
Sugar
Bitch Better Have My Money
YAP
Bitch Better Have My Money
Somebody
Thinking Out Loud
Talking Body
Talking Body
Know Yourself
Worth It
You Know You Like It
You Know You Like It
Time of Our Lives
Stole the Show
NPT
FourFiveSeconds
FourFiveSeconds
Take Me To Church
Take Me To Church
Ayo
Energy
Truffle Butter
Dear Future Husband
One Last Time
Lib
One Last Time
Lay Me Down
I Want You To Know
I Want You To Know
Throw Sum Mo
Slow Motion
Legend
Centuries
Centuries
All Day
King Kunta
Elastic Heart
Stay With Me
Stay With Me
American Oxygen
American Oxygen
Riptide
Blessings
Top Tracks in The United States

逆向工程的重要原因之一是:

寻求帮助对特定系统进行逆向工程的问题是题外话,除非他们证明了对所涉及的概念的理解并清楚地确定了特定问题。

......你似乎不理解“所涉及的概念”。这是因为我要求一个“二进制”,而你发布了一个像这样开头的粘贴 bin 链接:

00000000 11011010 11110111 11101111 00101111 01001100 00000000 11011010 11110111 11101111 00101111 00110000 11010011 10101010 00000001 00001001
00000100 01100110 01110010 01100101 01100101 00000001 00000111 01110000 01110010 01100101 01101101 01101001 01110101 01101101 00000001 00000111
(1998 similar lines omitted)

在逆向工程的上下文中,“二进制”是原始文件由于它是二进制文件,因此在解析它之前,您必须知道确切的文件格式,这似乎没有记录。粗略搜索前几个字节将一无所获(如果它们已知的,它们可以指示此特定文件类型幻数)。

但还没有失去一切。再次将 (*cough*) 二进制文件转换为真实文件并使用简单的十六进制查看器检查后,我注意到纯文本字符串,它之前的字节表示该文本字符串的长度。进一步检查 - 查看紧跟在文本字符串之后的值- 表明在长度/数据序列之前至少有一个其他字节并非所有数据都是纯文本,但这足以快速组成 C 程序并显示可以读取的内容。

程序最初所做的只是读取两个字节,显示它们,然后显示紧随其后的n 个字符。我让程序从一个“合理”的位置开始,在文件中更靠前的位置,因为前几个条目似乎没有遵循完全相同的格式。

这对于第一个条目来说没问题(我得到了几行数据一个文本字符串),但紧接着它就丢失了并且没有显示任何有用的东西。对“故障点”的仔细检查表明,至少有一个值是特殊的: hex78后跟另一个数字,并没有表明第二个数字是数据长度。所以我把它当作一个特例:“没有数据”,然后继续循环。

对于前 65 个条目,这一切正常:原始数据的常规列表、文本字符串,然后是其他 4 个原始数据列表。只是在那之后,同样的问题再次出现:列表“不同步”并再次显示乱码。进一步检查显示了另一个有问题的类型字节:08. 这似乎有两个字节的固定数据。当我也将其视为特殊情况时,我得到了更多有用的输出。

那时我停了下来,因为总体思路很清楚。我发现不值得进一步研究“原始”数据字节的含义,因为它们没有明确指示“时间戳”或“歌曲长度”。第一组 16 个字节可能表示散列或加密密钥;其他 4 个集合,全部为 20 个字节,可能是您要查找的数据 - 但它们不是常规格式。

我跳过了前 70 个左右的字节,因为我没有立即看到它们的用途——我强烈怀疑它们包含关于列表本身的元数据(例如,它的条目数)。

请注意,“文本字符串”是使用 UTF8 编码的。中的“未知”字符

"Skrillex and Diplo present Jack [c3][9c]"

实际上是“Jack Ü”的常规编码,是“美国DJ二人组,边组和合作项目”(来源)。识别诸如此类的“常规”数据序列是一项获得的技能(并且验证解释是否有效是普通常识;这只是快速查找维基百科)。

事不宜迟,我用比写这篇文章更短的时间编写了以下 C 程序。

#include <stdio.h>

int main (void)
{
    FILE *f = fopen ("spotify.bin", "rb");
    int i,type,len;

    if (!f)
    {
        printf ("no file?\n");
        return 0;
    }

    fseek (f, 0x45, SEEK_SET);

    do
    {
        type = fgetc(f);
        if (type == EOF)
            break;
        type &= 0xff;
        len = fgetc(f) & 0xff;

        printf ("type %02X len %02X: ", type, len);
        switch (type)
        {
            case 0x08:
                i = fgetc(f);
                printf (" %02X", i & 0xff);
                printf ("\n");
                break;
            case 9:
                printf ("\"");
                while (len--)
                {
                    i = fgetc(f);
                    if (i >= ' ' && i <= '~')
                        putchar (i);
                    else
                        printf ("[%02x]", i & 0xff);
                }
                printf ("\"\n");
                break;
            case 0x78:
                printf ("\n");
                break;
            default:
                while (len--)
                {
                    i = fgetc(f);
                    printf (" %02X", i & 0xff);
                }
                printf ("\n");
        }
    } while (1);

    return 0;
}