1 (изменено: Xameleon, 2017-02-11 12:18:15)

Тема: WSC: Script Component для чтения ресурсов из файлов через res протокол

Решил эту затею в отдельную тему вынести. Вдруг кому пригодится. А если повезёт, то может кто и допилит дальше.

Пересобрал код в виде WSC resReader.wsc.
Компонент содержит методы:

Open - открытие ресурса (всего лишь принимает имя файла)
GetStrings - чтение строковой таблицы по ID
GetString - чтение строки по ID
GetIcon - чтение содержимого иконки
GetBitmap - чтение содержимого рисунка

Пример работы с компонентом:


/* Restart in CScript */
if(WScript.FullName.match(/CScript/gi) == null){
	new ActiveXObject("WScript.Shell").Run("cscript \"" + WScript.ScriptFullName + "\"")
	WScript.Quit();
}

var StdOut = WScript.StdOut
var StdIn = WScript.StdIn

with (GetObject("script:file:resReader.wsc")){
	/* Opening file */
	Open("shell32.dll")

	StdOut.WriteLine("1) Loading STRINGTABLE 337 from from \"shell32.dll\"\r\n")
	
	/* Reading STRINGTABLE resource */
	var Strings = GetStrings(337)
	StdOut.WriteLine("String table 337 contains " + Strings.Count + " strings\r\n")

	/* Building STRINGTABLE visualisation */
	var arr = [], item
	for(var i=0;i < Strings.Count;i++){
		item = Strings.Item(i)
		arr.push(item.id + ", \"" + String(item).replace(/\"/g,"\\\"") + "\"")
	}
	StdOut.WriteLine("{\r\n" + arr.join("\r\n") + "\r\n}\r\n")

	StdOut.WriteLine("2) Input id resource for checking")

	/* Сheck the existence of the resource */
	var id = StdIn.ReadLine()
	if(Strings.Exists(id)){
		StdOut.WriteLine("Resource \"" + id + "\" found in string table\r\n")
		StdOut.WriteLine("It's value is \"" + Strings.ItemByID(id) + "\"\r\n")
	} else {
		StdOut.WriteLine("Resource \"" + id + "\" not found in string table\r\n")
	}
	
	/* Loading icon resource */
	StdOut.WriteLine("3) Loading ICON resource 203... \r\n")
	with(new ActiveXObject("ADODB.Stream")){
		Type = 1;
		Open();
		Write(GetIcon(203));
		SaveToFile("testImage.png", 2);
	}

	StdOut.WriteLine("Press ENTER key to show the image...")

	StdIn.ReadLine();
	
	new ActiveXObject("WScript.Shell").Run("testImage.png");
}
Post's attachments

resReader.wsc 3.39 kb, 10 downloads since 2017-02-10 

You don't have the permssions to download the attachments of this post.
Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

2

Re: WSC: Script Component для чтения ресурсов из файлов через res протокол

Xameleon, вновь твои идеи будоражат мое сознание.
Я и раньше пробовал извлекать ресурсы с помощью протокола res:\\ но скудность документации и собственных знаний оборвали этот процесс.
К сожалению, приведенный пример не отвечает на оказавшиеся для меня тупиковыми вопросы. Может быть совместными усилиями сможем найти на них ответ?

  1. Существующие просмотрщики ресурсов (тот же ResEdit, например) показывают совсем иной перечень ресурсов (диалоги, иконки, битмапы) нежели то, что извлекается с помощью протокола res:\\. Xameleon, а ты как вычислил эти цифири 337, 203 ? Методом "научного тыка"?

  2. Есть ли какой либо способ с помощью res:\\ получить перечень ресурсов?

  3. Самое востребованное действие - получить дефолтовую иконку файла. Я вот так и не смог этого сделать - пришлось прибегать к WinAPI.

3

Re: WSC: Script Component для чтения ресурсов из файлов через res протокол

mozers
А в чём суть научного тыка? Открываем ru-RU\shell32.dll.mui в PEViewer. На вкладке Ресурсы смотрим в String и находим нужное в 337. Так?

4

Re: WSC: Script Component для чтения ресурсов из файлов через res протокол

2Flasher
Спасибо за подсказку (я то искал в c:\windows\system32\shell32.dll).
В c:\WINDOWS\System32\ru-RU\shell32.dll.mui действительно 337 String имеется. Правда с помощью ResEdit его найти затруднительно. Зато в PE Explorer и ResHacker его действительно можно найти в блоке String.
Хорошо, а тогда 203 где искать?

5

Re: WSC: Script Component для чтения ресурсов из файлов через res протокол

mozers
В shell32.dll. ICLView номера показывает.
Не про PE Explorer пишу, а про то, к чему руки ближе, - плагины ТС.

Хотя у меня какой-то сломанный png создаётся. Определяется как cel.

Post's attachments

testImage.png
testImage.png 3.66 kb, 5 downloads since 2017-02-11 

You don't have the permssions to download the attachments of this post.

6

Re: WSC: Script Component для чтения ресурсов из файлов через res протокол

Данное изображение (комп с глобусом) видят все редакторы ресурсов. Но все они показывают это изображение (самое большое - 255х255) как одно из 8 входящих в набор одной из встроенных икон.
Иконка эта числится под номером 18 (ResHacker) 0016 (ICLView). Все просмотрщики позволяют сохранить это как файл ico содержащих все 8 иконок.
Запрос res://C:\windows\system32\shell32.dll/#3/#203 извлекает это изображение как файл png!
Это что же, получается что содержимое и местоположение реального ресурса и может быть совсем не связано ни с содержанием запроса res:// ни с его результатом???
Наверное, это все таки неверно и есть какое то четкое соответствие...

7

Re: WSC: Script Component для чтения ресурсов из файлов через res протокол

Flasher, твой testImage.png какой то изуродованный. Предлагаю использовать скриптик попроще:

url = "res://C:\windows\system32\shell32.dll/#3/#203"

With CreateObject("MSXML2.XMLHTTP")
	.Open "GET", url, False
	.Send
	data = .responseBody
End With

With CreateObject("SAPI.spFileStream")
	.Open "out.png", 2
	.Write data
	.Close
End With

8

Re: WSC: Script Component для чтения ресурсов из файлов через res протокол

То же самое.

9 (изменено: Xameleon, 2017-02-11 19:11:11)

Re: WSC: Script Component для чтения ресурсов из файлов через res протокол

mozers

вновь твои идеи будоражат мое сознание smile

Приветствую. Рад, что пригодилось. ) Если примите участие в "допиливании", буду ещё больше рад !

+ открыть спойлер

Рядом ещё тема с форматированием даты, времени и чисел используя "двигло" msxml . Как говорится - welcome.

но скудность документации и собственных знаний оборвали этот процесс.

Не поверите, я как раз от туда и подчерпнул всю информацию. )))
Именно ссылки с этой страницы привели меня к необходимой информации:
1) типы ресурсов
2) Описание формата STRINGTABLE

По поводу расположения ресурсов в mui файлах, я так понимаю Flasher, вас уже проинформировал. Мы как раз обсуждали этот момент тут:

Данное изображение (комп с глобусом) видят все редакторы ресурсов. Но все они показывают это изображение (самое большое - 255х255) как одно из 8 входящих в набор одной из встроенных икон.
Иконка эта числится под номером 18 (ResHacker) 0016 (ICLView). Все просмотрщики позволяют сохранить это как файл ico содержащих все 8 иконок.
Запрос res://C:\windows\system32\shell32.dll/#3/#203 извлекает это изображение как файл png!

Несколько раз перечитал Ваше последнее сообщение, но не смог понять, почему такой вывод:

Это что же, получается что содержимое и местоположение реального ресурса и может быть совсем не связано ни с содержанием запроса res:// ни с его результатом???
Наверное, это все таки неверно и есть какое то четкое соответствие...

Наборы иконок идут группой. От самой большой к самой маленькой: 203 - 210
203 - 256x254
204 - 64x64
205 - 48x48
206 - 40x40
207 - 32x32
208 - 24x24
209 - 20x20
210 - 16x16

Вроде всё логично ?

P.S Наваял интерактивный скрипт. Ностальгия по паскалю... ))

Post's attachments

interactive.zip 2.52 kb, 3 downloads since 2017-02-11 

You don't have the permssions to download the attachments of this post.
Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

10

Re: WSC: Script Component для чтения ресурсов из файлов через res протокол

2Xameleon
Да не "катит" такая логика.
Во-первых - почему именно 203? Почему иконка вдруг сохраняется как PNG?
Во вторых, res://C:\windows\system32\shell32.dll/#3/#204 должно извлечь 2ю иконку, однако извлекается какой то мусор (как у Flasherа)?
Да, и, пожалуйста, не называйте меня в множественном числе (я еще маленький).

11 (изменено: Xameleon, 2017-02-11 23:10:20)

Re: WSC: Script Component для чтения ресурсов из файлов через res протокол

mozers, теперь понял о чём речь. Выгрузил через Resource Hacker этот же ресурс. Наблюдаю такое же странное содержимое. Хм. Буду разбираться. ) Видимо это тоже специальным образом форматированные данные, как и STRINGTABLE.

почему именно 203

Честно говоря, в этом случае, взял первый попавшийся. А иконки меньшего размера в голову не пришло проверить.

Да, и, пожалуйста, не называйте меня в множественном числе (я еще маленький).

Пардоньте, я не против, но форум обязывает. ) Да и к тому же я сам не так уж стар. ))

UPD

Провёл исследование. Выгрузил из Resource Hacker ресурс как ".bin", и как ".ico". Сравнил содержимое. У ico файла присутствует заголовок, а у bin он отсутствует. В остальном тела файлов совпадают.

UPD 2

По ходу формат заголовка такой:
http://www.codeguru.com/cpp/w-p/win32/t … ources.htm

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

12

Re: WSC: Script Component для чтения ресурсов из файлов через res протокол

Я тоже провел собственное исследование.
С номером - все нормально (соответсвует PE Explorer). Видимо ResHacker как то иначе нумерует.
Крупные иконы (255х255) хранятся в формате png, поэтому их так легко извлечь. Их даже обычный html показывает.

<HTML>
<BODY>
<IMG src="res://shell32.dll/3/1">
</BODY>
</HTML>

Такие же иконы, но помельче, хранятся в виде набора ico. Протокол res:// извлекает их скопом, так, что не понимает ни один вьюер.
Чтобы их увидеть, надо эти данные обработать. Алгоритм заморочанный донельзя. Реализовать на vbs/js, боюсь, не получится. А если и получится, то тормоза будут - дикие.

13 (изменено: Xameleon, 2017-02-12 02:07:07)

Re: WSC: Script Component для чтения ресурсов из файлов через res протокол

mozers, ну не будем опускать руки. ) Пока что я понял, что Icon Group содержит всю информацию об иконках в разделе Icons. Задача выяснить - можно ли в обратную сторону - зная идентификатор иконки, узнать какой группе она принадлежит.

Вот код, на котором я пока что отлаживаюсь. Это получение информации о нашем злосчастном ресурсе ICON 203. Информация о нём хранится в ICON GROUP 18.

Один из источников инфы:https://msdn.microsoft.com/en-us/library/ms997538.aspx


Dim oReader
Dim oStream
Dim i
Dim sTmp

Set oReader = CreateObject("MSXML2.XMLHTTP")
oReader.Open "?","res://shell32.dll/14/18"
oReader.Send

Dim imgCount, nImg

print("Reserved: " & GetBytes(2))
print("Type: " & GetBytes(2))
imgCount = GetBytes(2)
print("ImageCount:" & imgCount)

For nImg = 1 to ImgCount
	print("Width: " & GetBytes(1))
	print("Height: " & GetBytes(1))
	print("Colors: " & GetBytes(1))
	print("Reserved: " & GetBytes(1))
	print("Planes: " & GetBytes(2))
	print("BitsPerPixel: " & GetBytes(2))
	print("ImageSize: " & GetBytes(4))
	print("ImageOffset: " & GetBytes(2))
	print("-----------------------------")
Next

MsgBox sTmp

Function print(text)
	sTmp = sTmp & text & vbCrlf
End Function

Function GetBytes(n)
	GetBytes = AscB(MidB(oReader.ResponseBody,i+1,n))
	i = i + n
End Function
Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

14

Re: WSC: Script Component для чтения ресурсов из файлов через res протокол

Исправлю своё ложное утверждение:

Протокол res:// извлекает их скопом

Если использовать в res:// запросе RT_ICON(3), то по указанному номеру извлекается конкретная иконка в формате ico, но вот только без 22 байтного заголовка.
Т.е. сейчас задача-минимум состоит в том чтобы добавить эти 22 байта, используя инфу, извлеченную из RT_GROUP_ICON(14) (см. пример by Xameleon выше).

15

Re: WSC: Script Component для чтения ресурсов из файлов через res протокол

mozers, именно так ! ) Но я пока всё-таки ищу способ связи от идентификатора иконки к группе, которой она принадлежит. ) Заголовок то сделать, вроде не проблема.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

16

Re: WSC: Script Component для чтения ресурсов из файлов через res протокол

Разрази меня гром, чтобы там не писали разные умники, мои многочисленные эксперименты показывают что все 22 байтные заголовки любых ico-шек различаются только 15 и 16 байтом!
Xameleon, имхо связывать надо от группы к иконке, а наоборот получится только тупым перебором всех групп подряд с поиском нужной.

17 (изменено: Xameleon, 2017-02-13 10:54:07)

Re: WSC: Script Component для чтения ресурсов из файлов через res протокол

mozers,
1) О ! Интересно. ) Я еще не сравнивал.
2)

имхо связывать надо от группы к иконке, а наоборот получится только тупым перебором всех групп подряд с поиском нужной.

Согласен. Тоже думал об этом. Но интересно - как же тогда работает API FindResource. ПМСМ, сомневаюсь, что тупым перебором.

UPD
Ещё немного подумал... В принципе можно сделать функцию LoadImage(id,type)
И набор констант типа:

Const PNG = 0
Const ICON64 = 1
...

И на основании их подсовывать заголовок. Но как-то.... не аккуратненько )

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

18 (изменено: mozers, 2017-02-13 14:07:19)

Re: WSC: Script Component для чтения ресурсов из файлов через res протокол

В общем, если внимательно (а не так, как я вчера) прочитать документацию, то окажется что умники - абсолютно правы.
Сначала по запросу типа res://shell32.dll/3/46 считываем данные.
Если вначале данных присутствует строка "PNG", то просто сохраняем данные как файл png.
Иначе вставляем в начало константу - hex-строку "0000010001002020200000000000" (т.к. Винда и все вьюеры - умные и игнорируют неверные данные о размере и цвете иконки которые задаются в этом блоке).
Затем надо вставить 4байтовую строку, указывающую размер считанных нами данных (вставить тут ерунду не получится - этот параметр проверяется строго). Получится что то типа "88090000".
Теперь - опять константа "16000000" указывающая на смещение данных.
Ну а теперь - сами данные.
Теперь все это в склеенном виде можно сохранить как файл ico.
Таким образом, для просмотра единичных иконок нет никакой необходимости извлекать какую то дополнительную инфу.

19 (изменено: Xameleon, 2017-02-13 16:36:33)

Re: WSC: Script Component для чтения ресурсов из файлов через res протокол

mozers, не понял. Поля заголовка должны же содержать шрину, высоту, цветность и т.п. параметры иконки. O_o Как при этом заголовок может быть общей константой для разных иконок ?

UPD
Пардон, перечитал. Увидел. Ну на мой взгляд некорректно так поступать. )

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

20 (изменено: mozers, 2017-02-13 23:13:12)

Re: WSC: Script Component для чтения ресурсов из файлов через res протокол

Xameleon
Ну, например, PE Explorer при сохранении из ресурсов одинарных ico-нок поступает именно так "некорректно".
В первом грубом приближении получается как то так - IconExtractor.vbs:

On Error Resume Next

file = "c:\Windows\SYSTEM32\shell32.dll"
' file = "c:\Program Files (x86)\Skype\Phone\Skype.exe"

inum = 0
Do
	inum = inum + 1
	With CreateObject("MSXML2.XMLHTTP")
		.Open "GET", "res://" & file & "/#3/#" & inum, False
		.Send
		idata = .responseBody
	End With
	ilen = LenB(idata)
	If ilen = 0 Then WScript.Quit

	With CreateObject("SAPI.spFileStream")
		If AscB(idata) = &H89 Then ' ----- Save as PNG
			.Open inum & ".png", 2
			.Write idata
			.Close
		Else ' ---------- Save as ICO
			.Open inum & ".ico", 2
			.Write CInt(0) 'reserved
			.Write CInt(1) 'type
			.Write CInt(1) 'count

			.Write CByte(32) 'width
			.Write CByte(32) 'height
			.Write CByte(32) 'colors
			.Write CByte(0) 'reserved
			.Write CInt(0) 'planes
			.Write CInt(0) 'bpp
			.Write CLng(ilen) 'size
			.Write CLng(22) ' offset
			.Write idata
			.Close
		End If
	End With
Loop

21

Re: WSC: Script Component для чтения ресурсов из файлов через res протокол

mozers, запустил, получил несколько дёрганий курсора, но иконки выгрузились успешно ! ) Клёво ! Завтра изучу подробнее код. ) Сэр, крайне благодарен вам за активное участие ! Начинаю чувствовать, что не одинок в своих экспериментах.

+ открыть спойлер

https://68.media.tumblr.com/dc2acffbea837dc5277bb1b469aafbb7/tumblr_n7u8czdwFI1qzs5cqo1_500.gif

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

22

Re: WSC: Script Component для чтения ресурсов из файлов через res протокол

Главная неприятность - то что номера иконок идут не подряд. В случае с shell32.dll скрипт обрывается на 64, поскольку следующий номер - 70. Вот как бы узнать все эти номера... Или придумать функцию, получающую следующий доступный номер...
Можно узнать номера иконок входящих в одну группу (из RT_GROUP_ICON), но с остальными - тоже самое, т.к. номера групп тоже не подряд идут.

23 (изменено: Xameleon, 2017-02-14 13:07:06)

Re: WSC: Script Component для чтения ресурсов из файлов через res протокол

mozers, ага. ) Именно так. Более того, идентификаторы иконок и групп могут быть строковыми. Например в файле explorer.exe есть группа "ICO_MYCOMPUTER". Видимо есть 2 пути:
1) Разбирать весь PE заголовок через ADODB.Stream / SAPI.spFileStream и находить все эти данные внутри и тогда вообще можно отказаться от res протокола. )))

2) Забить на поиск и реализовать по принципу, как я описывал тут.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

24 (изменено: Xameleon, 2017-02-15 15:23:06)

Re: WSC: Script Component для чтения ресурсов из файлов через res протокол

Ещё одна интересная альтернативка.


Const adSaveCreateOverWrite = 2
With CreateObject("CDO.Message").AddAttachment("res://shell32.dll/3/1")
	MsgBox .ContentMediaType
	.GetDecodedContentStream.SaveToFile "1.png", adSaveCreateOverWrite
End With
Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

25

Re: WSC: Script Component для чтения ресурсов из файлов через res протокол

Xameleon
Выдаёт text/html и сохраняет пустой png.