编程查找MTK手机里的图片、铃声,文字资源

  当初以为可以学习嵌入式的东西,(不过还好了,电路的东西学不会,数学又太高深了)结果刷了一段时间手机,这个程序就是我在刷机的时候写下来的。为了写这个东西,我专门花时间看了MID,WAVE,GIF的格式,主要就是看怎么找出他们的开始位置和大小。
 
 【铃声】
   声音文件的格式有很多种,比如MID,WAVE,MP3等。
  【1】WAVE文件的简略格式:
  ID:   4 BYTES  'RIFF'   --固定RIFF开头的
  size: 4 bytes           --是wave音乐文件的大小,不包括ID和size在内
  TYPE  4 bytes   'WAVE'  --类型

  以下是我自己写的查找WAVE的代码片段:

  if find(addr, filesize, addr, riff, 4) = 0 then break;     //find 是我自己写的查找函数。 
        mem.Position := addr + 1; //指向下一个位置
        waveaddr := addr - 3; //记录WAVE开始位置
        mem.Read(wavesize, 4);
        wavesize := wavesize + 8;
        mem.Read(buf, 4);
        if (buf = $45564157) and (wavesize < $100000) then
        begin //比较是不是WAVE
          music[j] := waveaddr;         //保存开始位置和大小
          inc(j);
          music[j] := wavesize;
          inc(j);
        end;
        application.ProcessMessages;
      until addr >= filesize - 10;

   【2】MID文件的简略格式
    "MThd"+00000006+fffff+nnnn+dddd
    固定以"MThd"开头,06 是总是06,描述的是f,n,d所占的字节数,NNNN是轨道数.
    接下来就是轨道了,固定以"MTrk"开头,接下来的四个字节描述了该轨道的大小,不包括"MTrk"和本身的四个字节.
    
  以下是我自己写的查找WAVE的代码片段:
      repeat
        if find(addr, filesize, addr, mthd, 4) = 0 then leave := true;
        mem.Position := addr + 1;
        midaddr := addr - 3; //记录mid文件开始位置
        mem.Read(buf, 4);
        if redword(buf) <> $06 then break;
        mem.Read(temp, 2);
        if reword(temp) > 2 then break;
        mem.Read(temp, 2);
        if reword(temp) > 20 then break;
        i := reword(temp); //记录轨道数
        count := i;
        mem.Read(temp, 2);
        if temp = 0 then break;
        midsize := 0;
        repeat
          mem.Read(buf, 4);
          mtrk := buf;
          ok := false;
          if mtrk <> $6B72544D then ok := true;
          mem.Read(buf, 4); //读取一个轨道的大小
          midsize := midsize + redword(buf); //累加
          mem.Position := mem.Position + redword(buf);
          i := i - 1;
          if ok = true then break;
        until i = 0;
        midsize := midsize + $E + (count * 8);
        if (ok = false) and (midsize < $100000) then
        begin
          music[j] := midaddr;
          inc(j);
          music[j] := midsize;
          inc(j);
        end;
        application.ProcessMessages;
   until (addr >= filesize - 10) or leave = true;
【图片】
   图片我主要看了gif的文件格式,大小还真的是不好确定。
   89a版的GIF文件才支持动画
   固定以 gif89a开头
   接着就是逻辑屏幕描述块,图像描述块,图像压缩数据,图像控制块等,都有相应的开头和结束标记,可以baidu一下
   GIF文件最终以3B结尾。

 以下是我的代码片段:
      repeat
      if find(addr, filesize, addr, gif, 6) = 0 then break;
      gifaddr := addr - 5; //gif的地址
      mem.Position := addr + 1;
      mem.Read(temp, 2);
      if temp > $140 then continue;
      mem.Read(temp, 2);
      if temp > $140 then continue;
      mem.Read(n, 1);
      gifsize := 13;
      if (n and $80) > 0 then //判断有没有全局颜色列表
      begin
        m := (n and 15) + 1;
        d := mypower(2, m);
        gifsize := gifsize + d * 3;
      end;
      mem.Position := gifaddr + gifsize;


      while true do
      begin
        mem.Read(n, 1);
        if n = $21 then
        begin
          mem.Position := mem.Position + 1;
          mem.Read(n, 1);
          gifsize := gifsize + n + 4;
          mem.Position := gifaddr + gifsize;
          continue; //继续下一次循环
        end;
        if n = $2C then
        begin
          mem.Position := mem.Position + 4;
          mem.Read(temp, 2);
          if temp > $140 then continue;
          mem.Read(temp, 2);
          if temp > $140 then continue;
          mem.Read(n, 1);
          gifsize := gifsize + 11;
          if (n and $80) > 0 then //判断有没有局部颜色列表
          begin
            m := (n and 15) + 1;
            d := mypower(2, m);
            gifsize := gifsize + d * 3;
          end;
          mem.Position := gifaddr + gifsize;
          continue; //继续下一次循环
        end;

        if (n <> 0) and (n <> $21) and (n <> $2C) and (n <> $3B) then
        begin
          while true do
          begin
            gifsize := gifsize + n + 1;
            mem.Position := gifaddr + gifsize;
            mem.Read(n, 1);
            if n = 0 then
            begin
              gifsize := gifsize + 1;
              break;
            end;
          end;
          mem.Position := gifaddr + gifsize;
          continue; //继续下一次循环
        end;

        if n = $3B then
        begin
          gifsize := gifsize + 1;
          if gifsize < $10000 then
          begin
            giftable[i] := gifaddr;
            inc(i);
            giftable[i] := gifsize;
            inc(i);
            break;
          end;
          if gifsize > $10000 then break;

        end;
      end;

    until addr - 10 > filesize;
【文字】
    MTK手机里的汉字是以UNICODE格式直接保存的。
    可以从Ok开始的位置查找。这个是和手机对比之后发现的。
    附件里的
    function UnicodeToAnsi(SubUnicode: string): string; //是将unicode码转换为汉字的函数
     程序写完后,测试结果和之前猜想的一样,MTK的资源是没有经过变换,直接存储到FLASHE里的。

 以上是我以前刷机的时候做的一点小研究,附件里的代码可是我真正刚开始学习DELPHI写下的,可以说是处女show,不过一直没做过修改。
 觉得挺好玩的就发上来,可以找出图片,声音,和文字,或许还有其他格式的。。。不过需要仪器把手机里的flash中的内容读到电脑上,没有仪器的可以百度"MTK字库下载"玩一下。

上传的附件 MTKrESOURCEEDIT.rar