Нахождение строкового идентификатора ресурса

Где хранится идентификатор ресурса таблицы строк? Я могу перечислить строки в таблице, но не существует какого-либо идентификатора "необработанный ресурс", это просто (массив) USHORT (длина), за которым следуют широкие символы (строка), есть без идентификатора.

PIMAGE_RESOURCE_DIR_STRING_U = ^TIMAGE_RESOURCE_DIR_STRING_U;
TIMAGE_RESOURCE_DIR_STRING_U = Record
  Count : USHORT;//Word;
  Name  : Array [0..0] of WideChar;
End;

PIMAGE_RESOURCE_DATA =^TIMAGE_RESOURCE_DATA;
TIMAGE_RESOURCE_DATA = Record
  rt_type :  DWORD; //RT_STRING
  lpName  :  ShortString; //tables name
  Address :  PDWORD; //address of the table
  dwSize  :  DWORD; //size of the data
end;

procedure GUIDataToString(IRD: TIMAGE_RESOURCE_DATA);
Type
  TStringArray = Array of String;


  Function SplitString(P: PByte; dwplen: Int32): TStringArray;
  //P is a Pointer to the string table, dwPLen is the size of the table
  Var
    Index : Int32;
    offset: Int32;
    dwLen : WORD;
    ST_ID : NativeUInt;
    rt_str: PIMAGE_RESOURCE_DIR_STRING_U;
  Begin
    Index := 0; //String Index
    offset:= 0;
    while (offset <= dwplen) do
    Begin
      SetLength(Result, Length(Result)+1);

      rt_str        := PIMAGE_RESOURCE_DIR_STRING_U(@P[offset]);
      Result[Index] := NameToStr(rt_str);
      //
      Inc(offset, (rt_str.Count * sizeof(WideChar) )+ sizeof(WORD));
      Inc(Index);
    End;
  End;

Var
  Table     : TStringArray;
  dwStrings : DWORD;
  I         : Int32;
  //d         :
begin
  Table   := SplitString(PByte(IRD.Address), IRD.dwSize);
  dwStrings := Length(Table);
  Memo1.Lines.Add('STRINGTABLE');
  Memo1.Lines.Add('{');

  for I := 0 to dwStrings-1 do
  Begin
    Memo1.Lines.Add(#9+Table[I]); //#9 is TAB
  End;
   Memo1.Lines.Add('}');
end;

Я прочитал ресурсную строку (тип) может быть приведен к PResStringRec Whos .Identifier поле даст идентификатор, но, я попробовал с моими "необработанными строками", и это случайное большое число (сравниваемые идентификаторы, которые дает resedit), какие-либо предложения о том, как найти идентификаторы?

https://i.imgur.com/kRGmiKG.png

2 ответа

Решение

В самой строковой таблице нет идентификаторов. Строковые ресурсы организованы в пакеты по 16. Строковый идентификатор на самом деле представляет собой 16-битное целое число, где старшие 12 бит идентифицируют индекс пакета в таблице, а младшие 4 бита идентифицируют индекс строки в пакете. Раймонд Чен обсуждает это в своем блоге MSDN:

Формат строковых ресурсов

Какой максимальный числовой идентификатор ресурса разрешен Win32?

Решено, где dwGroups - это число групп, dwGroup - индекс группы, содержащий строку, index - индекс строки (0..15) в группе.

  Function MakeRtStringId(dwGroups, dwGroup, Index: DWORD): DWORD;
  Var
    dwIndex : DWORD;
  Begin
    dwIndex := 4096 - (dwGroups - dwGroup);
    Result  := (dwIndex shl 4) or Index;
  End;

пожалуйста, отправьте альтернативные ответы, если вы придумали какие-либо.

[Править] серьезно, почему отрицательные голоса? Это потому что я не объясняю? Существует максимум 65535 строк, разделенных на группы по 16, что дает максимум 4096 групп. Строковые идентификаторы "начинаются" с 65535 и уменьшаются, поэтому, если у вас есть 15 строк, идентификаторы будут 65519, 65520, 65521, [...], 65535. и так далее, потому что последний идентификатор всегда 65535. Последняя цифра - это строка ее индекса в группе, потому что одна шестнадцатеричная цифра - 0-F (0-15). подсказки "группы по 16". спасибо Реми Лебо за информацию

Другие вопросы по тегам