Как прочитать бинарник приложения?

Все вопросы «а не подскажете, где мне найти...» обсуждаются только здесь.
vbStr
Новичок
Новичок
 
Сообщения: 44
Зарегистрирован: 04.04.2005 (Пн) 20:18

Как прочитать бинарник приложения?

Сообщение vbStr » 23.07.2005 (Сб) 16:29

Есть некоторая программа, которая после своей работы оставляет файлы, содержащие некоторые данные. Как образом можно прочитать информацию из таких файлов, сделав ее читаемой? Проще говоря, как вытащить из этих бинарников значения величин, числа и проч.?

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 23.07.2005 (Сб) 17:08

Не зная заранее их формата - никак.
Изображение

Jenizix
Географ
Географ
Аватара пользователя
 
Сообщения: 545
Зарегистрирован: 20.04.2004 (Вт) 20:52
Откуда: Москва

Сообщение Jenizix » 23.07.2005 (Сб) 17:51

Ну если канешна структура бинарника простая, то можно...
Ушел в себя, вернусь не скоро...

Если вам нужно сделать прозрачной только форму, а контролы на ней нет, то вам сюда!!!

vbStr
Новичок
Новичок
 
Сообщения: 44
Зарегистрирован: 04.04.2005 (Пн) 20:18

Сообщение vbStr » 23.07.2005 (Сб) 18:46

Кажется, я обратился по адресу! Меня поняли! Что за структура такая? Форматы данных? Где можно подробнее об этом посмотреть? Посоветуйте. Нужно очень добраться до информации из этих бинарников!
:?: Насколько простой может быть структура? Я пытался читать файл при помощи Getом. Сначала идут значения Empty, а потом - неизвестный тип, определенный пользователем.

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 23.07.2005 (Сб) 18:50

И как ты пытался его читать?
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

Jenizix
Географ
Географ
Аватара пользователя
 
Сообщения: 545
Зарегистрирован: 20.04.2004 (Вт) 20:52
Откуда: Москва

Сообщение Jenizix » 23.07.2005 (Сб) 19:09

Давай сюда этот бинарник, тока если он не большой < 200 Kb...
Но скорее всего это сделать не удастся, т.к. нужен точный формат структуры этих бинарников...
Ушел в себя, вернусь не скоро...

Если вам нужно сделать прозрачной только форму, а контролы на ней нет, то вам сюда!!!

vbStr
Новичок
Новичок
 
Сообщения: 44
Зарегистрирован: 04.04.2005 (Пн) 20:18

Сообщение vbStr » 24.07.2005 (Вс) 16:20

ANDLL. Пытался читать его Getом.
Код: Выделить всё
'Пытаемся вытащить данные!
FileNumber = FreeFile
Open pathLWork & "\" & "TEST.TEST" For Binary As #FileNumber
Do While Not EOF(1)
    Get #FileNumber, , FileBuffer
    Debug.Print FileBuffer
Loop
Close #FileNumber

Jenizix, для очень простой задачи файлы очень маленькие ~1Kb. Высылаю на твой mail. Посмотри, если не сложно. Ответ - в форум, у меня email - нет :).

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 24.07.2005 (Вс) 17:10

Может, так:
Код: Выделить всё
FileNumber = FreeFile
Open pathLWork & "\" & "TEST.TEST" For Binary As #FileNumber
FileBuffer =space(lof(FileNumber))
Get #FileNumber, , FileBuffer
Debug.Print FileBuffer
Close #FileNumber
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

vbStr
Новичок
Новичок
 
Сообщения: 44
Зарегистрирован: 04.04.2005 (Пн) 20:18

Сообщение vbStr » 25.07.2005 (Пн) 17:39

ANDLL, не работает! А при чем тут строчка из пробелов?

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 25.07.2005 (Пн) 18:36

КАК ЭТО НЕ РАБОТАЕТ?
Код: Выделить всё
Private Sub Form_Load()
Dim FileBuffer As String, FileNumber As Long
FileNumber = FreeFile
Open "C:\boot.ini" For Binary As #FileNumber
FileBuffer = Space(LOF(FileNumber))
Get #FileNumber, , FileBuffer
Debug.Print FileBuffer
Close #FileNumber
End Sub


Строчка из пробелов нужна для резервирования места.
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

vbStr
Новичок
Новичок
 
Сообщения: 44
Зарегистрирован: 04.04.2005 (Пн) 20:18

Сообщение vbStr » 25.07.2005 (Пн) 19:05

ANDLL, не горячись. VB говорит, что такой тип данных он не знает. Хорошо, место зарезервировали. А дальше что? У FileBuffer, в которую Get помещает считанную информацию тип String, а информация точно численная.

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 25.07.2005 (Пн) 20:44

А какие это числа(в смысле сколько байт приходится на одно число? два, четыре или восемь?)
Может так:
Код: Выделить всё
Private Sub Form_Load()
Dim FileBuffer() As Long, FileNumber As Long
FileNumber = FreeFile
Open "file" For Binary As #FileNumber
redim FileBuffer(LOF(FileNumber)\4)
Get #FileNumber, , FileBuffer
Debug.Print FileBuffer(0)
Close #FileNumber
End Sub
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

vbStr
Новичок
Новичок
 
Сообщения: 44
Зарегистрирован: 04.04.2005 (Пн) 20:18

Сообщение vbStr » 26.07.2005 (Вт) 16:32

ANDLL! Скорее всего, это Integer и Double. Но неизвестно, в каком порядке они расположены. Есть там еще какая-то сбивка и проч. защита от вот таких дел, которыми я занимаюсь :D

eagle-dwarf
Начинающий
Начинающий
 
Сообщения: 9
Зарегистрирован: 29.07.2005 (Пт) 10:16

Сообщение eagle-dwarf » 29.07.2005 (Пт) 10:38

Забавно, столкнулся с похожей проблемой, только у меня известен формат файла. но все равно выдрать из 16-ричного кода 10-чное значение числа у меня пока не получается. (вернее получается только для целых чисел)

1. проблема с GET'ом действительно есть - дело в том что в 16-ричном коде могут быть такие значения которые в строковой переменной хранятся некорректно (вот уж не знаю почему, но это кажется даже в справке по VBA написано).
2. но это пол беды, я столкнулся с тем что если читать бинарник по переменным Long,Singlе и Double то и они по неизвестной причиние принимают не численное значение а строковое. A Далее смотри пункт первый - Get возмущается что не понимает такого типа данных.

Я читаю бинарник побайтно в массив переменных типа Byte - в этом случае никаких проблем с Get'ом нет. А вот чего с ним дальше делать пока не сообразил (если бы у меня были только переменные типа Integer или Long то я знаю как это пересчитать а вот как пересчитваются числа с плавающей точкой я не помню).

eagle-dwarf
Начинающий
Начинающий
 
Сообщения: 9
Зарегистрирован: 29.07.2005 (Пт) 10:16

Сообщение eagle-dwarf » 29.07.2005 (Пт) 13:30

Вытянуть чило типа Integer (процедуре передаются два байта в той последовательности в которой они идут в бинарнике)

Код: Выделить всё
Function GetInteger(FirstByte, SecondByte As Byte)
Dim number As Long
number = CLng(FirstByte) + CLng(SecondByte) * 256
If number > 32767 Then number = number - 65536
GetInteger = CInt(number)
End Function

Вытянуть число типа Long
Код: Выделить всё
Function GetSingle(FirstByte, SecondByte, ThirdByte, FourthByte As Byte)
Dim number As Double
number = CDbl(FirstByte) + CDbl(SecondByte) * 256 + CDbl(ThirdByte) * 256 ^ 2 + CDbl(FourthByte) * 256 ^ 3
If number > 2147483647 Then number = number - 4294967296#
GetSingle = CLng(number)
End Function


Я думаю можно бы эти процедуры еще оптимизировать, но для меня пока и так сойдет

Что касается чисел с плавающей точкой, то тут сложнее, но так как мне оно тоже очень нужно и в любом случае придется сделать, то как только сделаю напишу

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 29.07.2005 (Пт) 13:33

Lasciate ogni speranza, voi ch'entrate.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 29.07.2005 (Пт) 13:34

А Long и Integer лучше получать не с помощью математических операторов (умножение и степень), а с помощью логических (Or).
Lasciate ogni speranza, voi ch'entrate.

eagle-dwarf
Начинающий
Начинающий
 
Сообщения: 9
Зарегистрирован: 29.07.2005 (Пт) 10:16

Сообщение eagle-dwarf » 29.07.2005 (Пт) 16:29

2alibek, а как с помощью логических операторов это провернуть, я чего-то не соображу никак?

За стандарт спасибки.

Но я уже нашел в сети код программки которая высчитывает Single

vbStr
Новичок
Новичок
 
Сообщения: 44
Зарегистрирован: 04.04.2005 (Пн) 20:18

Сообщение vbStr » 02.08.2005 (Вт) 20:26

[quote="eagle-dwarf"]Забавно, столкнулся с похожей проблемой, только у меня известен формат файла
2. но это пол беды, я столкнулся с тем что если читать бинарник по переменным Long,Singlе и Double то и они по неизвестной причиние принимают не численное значение а строковое. A Далее смотри пункт первый - Get возмущается что не понимает такого типа данных.
[quote]
eagle-dwarf, тебе доподлинно известен формат данных в файле? Т.е., тебе известен этот шаблон из какого-то источника или ты его сам разгадал? Я пытаюсь раскрыть неизвестный мне формат с переменным успехом: в целом структура файла ясна (лежат подряд записанные целые и дробные), но встречаются какие-то странные байты, которые сбивают процесс чтения.
Если открыть бинарник Блокнотом, то в этих сбойных местах стоят подряд несколько "пробелов", но при попытке "пробежать" через это место курсором происходит "проскакивание" курсора. Другими словами, обычно курсор за одно нажатие передвигается на один символ, а этих проблемных местах перескакивает сразу через несколько.
Мне известно, что это сделано намеренно. Кто-нибудь знает как эту нерегулярность в бинарном файле обойти?

eagle-dwarf
Начинающий
Начинающий
 
Сообщения: 9
Зарегистрирован: 29.07.2005 (Пт) 10:16

Сообщение eagle-dwarf » 03.08.2005 (Ср) 9:55

Формат моего файла мне не был известен, то есть я примерно представлял что там должно быть, но только примерно. Пришлось самому разгадывать. Хошо, что в файле содержались куски кода каждый из которых был описанием определенного объекта, а всего возможных типов объектов было 5.

Кстати, разгадывать 16-ричный код блокнотом жутко не удобно. Возьми любой редактор 16-ричного кода (hex-редактор). я очень быстро нашел в сети такой, который меня устроил. (WINHEX 12.2 русифицированный) могу скинуть тебе его на мыло - весит что-то вроде 700кб.

Далее, что касается пробелов то это код hex (20) если читать файл побайтно с проверкой содержания байта то можно просто вычислять такие байты и неучитывать при дальнейшем использовании.
Кроме того я не думаю что они уж совсем незакономерно расположены - скорее всего они маркируют конец (или начало) какой-то логически связанной записи. - потому что, если бы я хотел скрыть значения записанные в бинарный файл, то я бы не геморроился с хаотичным изменением в записях, а просто зашифровал бы данные любым из легкодоступных шифров. - это проще и надежнее.

Что касается проскакивания курсора - это глюки блокнота - скорее всего там находятся не пробелы, а какие-то управляющие символы, которые он не может воспринять. Раскрой файл hex-редакотором и посмотри какой там код если не 20 то это не пробелы. Чтобы узнать что же это за символ посмотри в таблице ASCII кодов.

vbStr
Новичок
Новичок
 
Сообщения: 44
Зарегистрирован: 04.04.2005 (Пн) 20:18

Сообщение vbStr » 03.08.2005 (Ср) 20:02

eagle-dwarf писал(а):Кстати, разгадывать 16-ричный код блокнотом жутко не удобно. Возьми любой редактор 16-ричного кода (hex-редактор). я очень быстро нашел в сети такой, который меня устроил. (WINHEX 12.2 русифицированный) могу скинуть тебе его на мыло - весит что-то вроде 700кб.

eagle-dwarf, я догадывался о существовании какого-либо "продвинутого блокнота", при помощи которого можно просматривать бинарные файлы. Но не знал, как такое средство назвать при поиске. Поэтому и не искал :D . Спасибо за информацию. Сам поищу в Сети рекомендованный тобой WinHex. Кстати, именно просматривая "краказябры" бинарника в Блокноте, я получил первое представление о структуре.

eagle-dwarf писал(а):Далее, что касается пробелов то это код hex (20) если читать файл побайтно с проверкой содержания байта то можно просто вычислять такие байты и неучитывать при дальнейшем использовании.
Кроме того я не думаю что они уж совсем незакономерно расположены - скорее всего они маркируют конец (или начало) какой-то логически связанной записи.

Выяснилось, что никакой сбивки не было :wink: . Я запостил свое сообщение, еще толком не проанализировав результаты. Но, всё равно, спасибо!

eagle-dwarf
Начинающий
Начинающий
 
Сообщения: 9
Зарегистрирован: 29.07.2005 (Пт) 10:16

Сообщение eagle-dwarf » 05.08.2005 (Пт) 20:31

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

Integer
Код: Выделить всё
Function GetInteger(FirstByte As Byte, SecondByte As Byte) As Integer
Dim number As Integer

If SecondByte < 128 Then
    number = FirstByte + SecondByte * 256
Else
    number = FirstByte + (SecondByte - 256) * 256
End If
GetInteger = number
End Function


Long

Код: Выделить всё
Function GetLong(FirstByte As Byte, SecondByte As Byte, ThirdByte As Byte, FourthByte As Byte) As Long
Dim number As Long

If FourthByte < 128 Then
    number = FirstByte + SecondByte * 256 + ThirdByte * 256 ^ 2 + FourthByte * 256 ^ 3
    Else
    number = FirstByte + SecondByte * 256 + ThirdByte * 256 ^ 2 + (FourthByte - 256) * 256 ^ 3
End If

GetLong = number
End Function


single
Код: Выделить всё
Function GetSingle(FirstByte As Byte, SecondByte As Byte, ThirdByte As Byte, FourthByte As Byte) As Single
Dim number As Single
Dim SignOfNumber As Integer
Dim Order As Integer

'Определение знака числа
If FourthByte < 128 Then 'Проверка знака числа
    SignOfNumber = 1
Else
    SignOfNumber = -1
    FourthByte = FourthByte - 128 'убираем из байта бит отвечающий за знак
End If
'Вычисление кода порядка - смещаем-увеличиваем порядок на один разряд т.к для порядка используется еще один бит (всего их 8) из следующего байта
Order = 2 * FourthByte
'Коррекция кодов порядка и мантиссы
If ThirdByte > 127 Then
      Order = Order + 1 ' если в том бите который в третьем байте отвечает за порядок есть 1 то соответственно прибавляем его к поярядку
      ThirdByte = ThirdByte - 128 'вычитаем значение этого бита из байта
End If
'Коррекция нормализованной мантиссы
If Order > 0 Then
     ThirdByte = ThirdByte + 128 'добавляем разряд - кажись это связано с тем что число высчитывается как 2точкаДробная, часть а записано оно как 0точка2Дробная часть
End If
'Вычисление мантиссы
' number = ((FirstByte / 256 + SecondByte) / 256 + ThirdByte) / 256
number = ThirdByte * 256 ^ -1 + SecondByte * 256 ^ -2 + FirstByte * 256 ^ -3
'Вычисление модуля числа
If Order > 126 Then
    For I = 1 To Order - 126
        number = number * 2
    Next I
Else
    For I = 1 To 126 - Order
        number = number / 2
    Next I
End If
'Коррекция знака числа
   If SignOfNumber < 0 Then
      number = -number
   End If
GetSingle = number
End Function



Double
так как я слямзил код вычисления Single из сети и всего-лишь подправил немного, то, когда создавал по его образу и подобию код для Double, так и не смог понять одной вещи. Это касается цикла при вычислении модуля числа. Если кто меня надоумит почему так, а не иначе, буду благодарен.

Код: Выделить всё
Function GetDouble(FirstByte As Byte, SecondByte As Byte, ThirdByte As Byte, FourthByte As Byte, b5 As Byte, b6 As Byte, b7 As Byte, b8 As Byte) As Double
Dim number As Double
Dim SignOfNumber As Integer
Dim Order As Integer
Dim Temp As Integer

'Определение знака числа
   If b8 < 128 Then 'Проверка знака числа
      SignOfNumber = 1
   Else
      SignOfNumber = -1
      b8 = b8 - 128
   End If
   
   Order = 16 * b8 'Вычисление кода порядка - смещаем-увеличиваем порядок на 4 разряда т.к для порядка используется еще 4 бит (всего их 11) из следующего байта

'Коррекция кодов порядка и мантиссы записанных в следующем байте
If b7 > 15 Then
    Temp = CInt(b7) 'временно сохраняем первоначальное значение седьмого байта
    Do
        b7 = b7 - 16
    Loop While b7 > 15 'полученое число соответствует 4 младшим битам в байте и относится к мантиссе
    Order = Order + (Temp - CInt(b7)) / 16 ' если в в четырех страших битах этого байта есть отличное от 0 число то оно относится к порядку значит его нужно перевести в 4 малдших байта и прибавить к порядку
End If
If Order > 0 Then 'добавляем разряд
     b7 = b7 + 16
End If
'вычисление мантиссы
number3 = b7 * 256 ^ -1 + b6 * 256 ^ -2 + b5 * 256 ^ -3 + FourthByte * 256 ^ -4 + ThirdByte * 256 ^ -5 + SecondByte * 256 ^ -6 + FirstByte * 256 ^ -7

'вычисление модуля числа
If Order > 1019 Then 'по какой-то причине в порядке отсутствует разряд по идее порядок должен быть больше 1021 но с 1021 не работает а с 1019 все отлично, мож объяснит кто?
    Order = Order - 1019
    For I = 1 To Order
        number = number * 2
    Next I
Else
    For I = 1 To 1019 - Order
        number = number / 2
    Next I
End If

'Коррекция знака числа
   If SignOfNumber < 0 Then
      number = -number
   End If
GetDouble = number
End Function

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 06.08.2005 (Сб) 6:08

Чё происходит вообще?..
Оператор Get берёт из файла данные любого типа. Это первое.

Второе.
Если очень хочется из отдельных байтов складывать float'ы, то
Код: Выделить всё
private type bytes
  b1 as byte
  b2 as byte
  b3 as byte
  b4 as byte
end type

private type float
  f as single
end type

sub asdf
  dim b as bytes, f as float
 
  b.b1=1
  b.b2=2
  b.b3=3
  b.b4=4

  lset f=b

  msgbox f.f
end sub
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

eagle-dwarf
Начинающий
Начинающий
 
Сообщения: 9
Зарегистрирован: 29.07.2005 (Пт) 10:16

Сообщение eagle-dwarf » 18.08.2005 (Чт) 12:20

маненько с опозданием :)
Get не все хватает, попробуй-ка им захватить подряд несколько типов данных (разных) - ругаться будет. Шумит что ему неизвестен такой пользовательский тип данных.
А твой вариант складывания не пойдет - так как складывает значения байтов, - то есть подходит только для переменных long и integer и то только в том случае если они имеют положительные значения.


Вернуться в Народный поиск

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 36

    TopList