> The "heap" resource: The next word is a size of the next block - contains
a
> number of words that follows. I don't know
> what is the meaning of this block yet. The next word should contain the
> magic number 0x1234 - I think this is the 1st object in the resource.
(i.e.
> Get Word at offset 2, multiply by 2(number of words), add 4(skip first 2
> words) and on this offset in the "heap" resource should be word containing
> 0x1234). The next word after the magic 0x1234 is a number of words in this
> block, i.e. multiply by 2 and add to the previous offset to get the
> position of the next "magic" number 0x1234.
according to my researches in the past i found out the following:

(not sure about that all, it's some time ago and i don't really know about
sci and i do not exactly now what you found out already - so if it's nothing
new for you what i write, then i apologize.)

so, the heap contains just the "raw" objects, each after another.

if you build a selector-table, you get the following: (997.voc)
0000: plane
0001: x
...
0020: name
...
1000: -objID-
1001: -size-
1002: -propDict-
1003: -methDict-
1004: -classScript-
1005: -script-
1006: -super-
1007: -info-

So first you need a starting pointer, where the Data of the Objects start.
(*) resource files usually include their resource type as the first word. i
do NOT count them here. so the first word is at offset 2, if you count that
way.

actually i don't now were to get this from. just try.

let's look at 64999.hep, a heap file from gabriel knight (my favourite game
;)

00000000:  91 00 32 01-00 00 34 12-09 00 16 00-28 00 00 00
00000010:  00 00 FF FF-00 80 F8 00-34 12 09 00-52 00 64 00

the 0x91 is the resource type. 0x0132 is the offset to the relocation data.
relocation is specific to the hunk (if i recall that right).
then a misterious zero word comes in. let's skip it.

the following words are following:
0x1234
0x0009
0x0016
0x0028
0x0000
0x0000
0xFFFF
0x8000
0x00F8
0x1234 again. this is the start of the next object (calm down, we can
calcualte the exact size ;)

let's look at the hunk (.scr) file, 64999.scr:

00000000:  82 00 D0 07 00 00 00 00 07 00 CE 01 DF 01 FC 01
00000010:  1A 02 38 02 71 02 98 02 00 10 01 10 02 10 03 10
                                   ^^^^^
00000020:  04 10 05 10 06 10 07 10 20 00 0A 00 91 00 A3 02

notice the 0x1000 at offset 0x16 (*).
the values are:
0x1000
0x1001
0x1002
0x1003
0x1004
0x1005
0x1006
0x1007
0x0020

0x16 ... look again at the values extracted from the heap.
you find it here. so the values above point to the beginning of this table.

right, but what does this table means? well, look at the selectors. 0x1000
is -objID-.
what the heck is a -objID-?
what the hell is the 0x1234 there? an id? :)

yes, you're right. we just got the table with the selectors.

hm, and our magic 0x16 offset at selector #2? #2 is selector 0x1002.
selector 0x1002 is -propDict-.

Properties. we're right here.

ok, let's combine the values with their names:

sel   name                   value

1000: -objID-                0x1234
1001: -size-                 0x0009
1002: -propDict-             0x0016
1003: -methDict-             0x0028
1004: -classScript-          0x0000
1005: -script-               0x0000
1006: -super-                0xFFFF
1007: -info-                 0x8000
0020: name                   0x00F8

well, 0x9 is the size, the number of selectors aka properties.

let's look at the name: if you look at the relocation table, you'll notice
that a relocation entry points on this, so this points into the heap.

heap at 0xF8 is: "Obj" 00

jeah, thats the name. we just hot the first object, the metaclass above all
other objects.

it's superclass is 0xFFFF, which means: none.
it's classid is 0 (if i recall this right).

well, let's look at the methods:

offset 0x28 in the hunk: (written as values)
as you see, these are pairs of values, so i write them as pairs.
0x000A
0x0091 0x02A3
0x0092 0x02AA
0x0045 0x02AB
0x0093 0x02AD
0x006A 0x02B4
0x0094 0x02C9
0x0095 0x02FC
0x0096 0x02D0
0x0097 0x02C0
0x0098 0x0331
0x1000  << another propdict, so i'll stop here
0x1002

0x0A seems to be the size - well, 0xA entries .. jep, that's exactly the
number of pairs before the next 0x1000, the start of another propdict.

the second value of the pairs is incrementing - so we'll assume it's an
offset.
the first value is (again) a selector index:

i'll lookup them in the 997.voc:

0x0091 0x02A3    new
0x0092 0x02AA    init
0x0045 0x02AB    doit
0x0093 0x02AD    dispose
0x006A 0x02B4    perform
0x0094 0x02C9    isClass
0x0095 0x02FC    isKindOf
0x0096 0x02D0    isMemberOf
0x0097 0x02C0    respondsTo
0x0098 0x0331    yourself

so, these are the methods, and the second column are script pointers.

let's reverse a simple one, for example init :)

hunk at 0x2AA:

48 ....

48 is opcode: ret

well, off course it's ret, because the next method starts immediately at
0x2AB :)

ok, let's reverse another method: "isClass".

it's offset is 0x2C9:

02C9: 67 0E                              pTos 0xe
02CB: 34 00 80                           ldi 0x8000
02CE: 12                                 and
02CF: 48                                 ret

you should now these stuff better than me :)
but anyway:

pTos 0xe
loads a property onto the stack, property 0xE. 0xE is an offset to the
property table, so it's property 0xE/2 = 7.

property: 0x7 is Obj.-info-, in this object 0x8000.

stack: 0x8000
ldi just loads an immediate constant into the stack.
stack: Obj.-info- 0x8000
and puts two popped values ANDed into the ACC.
stack: (Obj.-info-)&0x8000.

ret returns the ACC.

so our function is:

Obj.isClass()
{
  return -info-&0x8000;
}

well..

i hope that this somehow helps, if not, i apologize for producing senseless
traffic :)

bye,
felix domke


Reply via email to