mm: slub: print_hex_dump() with DUMP_PREFIX_OFFSET
Subsystems (3)
PATCH 1/1 mm: slub: print_hex_dump() with DUMP_PREFIX_OFFSET
Since commit ad67b74d2469d9b8 ("printk: hash addresses printed with %p"), The use DUMP_PREFIX_OFFSET instead of DUMP_PREFIX_ADDRESS with print_hex_dump() can generate more useful messages.
In the following example, it's easier get the offset of incorrect poison value with DUMP_PREFIX_OFFSET.
Before:
Object 00000000e817b73b: 00 00 00 00 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object 00000000816f4601: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object 00000000169d2bb8: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object 00000000f4c38716: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object 00000000917e3491: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object 00000000c0e33738: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object 000000001755ddd1: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b
After:
Object 00000000: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object 00000010: 63 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object 00000020: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object 00000030: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b a5
I think it might be worth to convert all DUMP_PREFIX_ADDRESS to DUMP_PREFIX_OFFSET for the whole Linux kernel.
$ git grep 'DUMP_PREFIX_ADDRESS' | cut -f1 -d"/" | sort | uniq -c 3 arch 140 drivers 12 fs 1 include 5 lib 2 mm
--- mm/slub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/slub.c +1 -1
@@ -528,7 +528,7 @@ static void print_section(char *level, char *text, u8 *addr, unsigned int length) {metadata_access_enable (); -print_hex_dump (level, text,DUMP_PREFIX_ADDRESS ,16 ,1 , addr, +print_hex_dump (level, text,DUMP_PREFIX_OFFSET ,16 ,1 , addr, length,1 );metadata_access_disable (); }
Signature · 1 line
2.18.0
David Rientjes
reviewerQuoted 16 lines · Miles Chen
Since commit
ad67b74d2469d9b8("printk: hash addresses printed with %p"), The useDUMP_PREFIX_OFFSETinstead ofDUMP_PREFIX_ADDRESSwithprint_hex_dump()can generate more useful messages.In the following example, it's easier get the offset of incorrect poison value with
DUMP_PREFIX_OFFSET.Before:
Object00000000e817b73b: 00 00 00 00 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object00000000816f4601: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object00000000169d2bb8: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object00000000f4c38716: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object00000000917e3491: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object00000000c0e33738: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object000000001755ddd1: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b
Quoted 9 lines
After:
Object 00000000: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object 00000010: 63 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object 00000020: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object 00000030: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b a5I think it might be worth to convert all
DUMP_PREFIX_ADDRESStoDUMP_PREFIX_OFFSETfor the whole Linux kernel.
I agree it looks nicer for poisoning, I'm not sure that every caller of print_section() is the same, however. For example trace() seems better off as DUMP_PREFIX_ADDRESS since it already specifies the address of the object being allocated or freed and offset here wouldn't really be useful, no?
Quoted 24 lines · David Rientjes
Quoted 16 lines · Miles Chen
Since commit
ad67b74d2469d9b8("printk: hash addresses printed with %p"), The useDUMP_PREFIX_OFFSETinstead ofDUMP_PREFIX_ADDRESSwithprint_hex_dump()can generate more useful messages.In the following example, it's easier get the offset of incorrect poison value with
DUMP_PREFIX_OFFSET.Before:
Object00000000e817b73b: 00 00 00 00 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object00000000816f4601: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object00000000169d2bb8: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object00000000f4c38716: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object00000000917e3491: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object00000000c0e33738: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object000000001755ddd1: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6bQuoted 5 lines
After:
Object 00000000: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object 00000010: 63 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object 00000020: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object 00000030: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b a5
Quoted 5 lines
I agree it looks nicer for poisoning, I'm not sure that every caller of
print_section()is the same, however. For exampletrace()seems better off asDUMP_PREFIX_ADDRESSsince it already specifies the address of the object being allocated or freed and offset here wouldn't really be useful, no?
While it looks nicer, it might be less useful for debugging. The point of obfuscated %p is that you can compare two "pointer" values for equality. So if you know that you freed object 00000000e817b73b from an earlier printk, then you can match it up to this dump. It's obviously not perfect since we're only getting the pointers at addresses that are multiples of 16, but it's a help.
Quoted 31 lines · Matthew Wilcox
Quoted 24 lines · David Rientjes
Quoted 16 lines · Miles Chen
Since commit
ad67b74d2469d9b8("printk: hash addresses printed with %p"), The useDUMP_PREFIX_OFFSETinstead ofDUMP_PREFIX_ADDRESSwithprint_hex_dump()can generate more useful messages.In the following example, it's easier get the offset of incorrect poison value with
DUMP_PREFIX_OFFSET.Before:
Object00000000e817b73b: 00 00 00 00 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object00000000816f4601: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object00000000169d2bb8: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object00000000f4c38716: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object00000000917e3491: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object00000000c0e33738: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object000000001755ddd1: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6bQuoted 5 lines
After:
Object 00000000: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object 00000010: 63 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object 00000020: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object 00000030: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b a5Quoted 5 lines
I agree it looks nicer for poisoning, I'm not sure that every caller of
print_section()is the same, however. For exampletrace()seems better off asDUMP_PREFIX_ADDRESSsince it already specifies the address of the object being allocated or freed and offset here wouldn't really be useful, no?
Quoted 6 lines
While it looks nicer, it might be less useful for debugging. The point of obfuscated %p is that you can compare two "pointer" values for equality. So if you know that you freed object
00000000e817b73bfrom an earlier printk, then you can match it up to this dump. It's obviously not perfect since we're only getting the pointers at addresses that are multiples of 16, but it's a help.
Thanks for the reply.
The value of 00000000e817b73b dump and the value earlier printk should be the same, Otherwise we have a serious problem because:
printf("%p", bad_ptr);print_hex_dump(bad_ptr);
and we see a different hashed address of bad_ptr in print_hex_dump(). I think it's a rare case but we still have a chance to see that case. DUMP_PREFIX_ADDRESS is useful for that case.
On the other hand, DUMP_PREFIX_OFFSET is useful for finding the offset of incorrect poison value easier.
Maybe I can print the offset of the bad poison value in check_bytes_and_report(). e.g.,
@@ -736,6 +736,7 @@ static int check_bytes_and_report(struct kmem_cache *s, struct page *page,
{
u8 *fault;
u8 *end;+ u8 *addr = page_address(page);
metadata_access_enable();
fault = memchr_inv(start, value, bytes);
@@ -748,8 +749,9 @@ static int check_bytes_and_report(struct kmem_cache
*s, struct page *page,
end--;
slab_bug(s, "%s overwritten", what);- pr_err("INFO: 0x%p-0x%p. First byte 0x%x instead of 0x%x\n",
- fault, end - 1, fault[0],
value);
+ pr_err("INFO: 0x%p-0x%p. First byte 0x%x instead of 0x%x,
offset=%tu\n",
+ fault, end - 1, fault[0], value,
fault -
+ addr);
and we can see the offset printed out:
=============================================================================
BUG kmalloc-1k (Tainted: G B ): Poison overwritten
-----------------------------------------------------------------------------
INFO: 0x(____ptrval____)-0x(____ptrval____). First byte 0x63 instead of 0x6b, offset=7052
INFO: Object 0x(____ptrval____) @offset=6272 fp=0x(____ptrval____)
and we can get the offset by: 7052 - 6272 = 780.
Quoted 5 lines · David Rientjes
I agree it looks nicer for poisoning, I'm not sure that every caller of
print_section()is the same, however. For exampletrace()seems better off asDUMP_PREFIX_ADDRESSsince it already specifies the address of the object being allocated or freed and offset here wouldn't really be useful, no?
The address is printed earlier before the object dump. Maybe that is sufficient and we could even reduce the number of digits further to have the display more compact? In this case two hex digits would do the trick.
Quoted 28 lines · David Rientjes
Quoted 16 lines · Miles Chen
Since commit
ad67b74d2469d9b8("printk: hash addresses printed with %p"), The useDUMP_PREFIX_OFFSETinstead ofDUMP_PREFIX_ADDRESSwithprint_hex_dump()can generate more useful messages.In the following example, it's easier get the offset of incorrect poison value with
DUMP_PREFIX_OFFSET.Before:
Object00000000e817b73b: 00 00 00 00 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object00000000816f4601: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object00000000169d2bb8: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object00000000f4c38716: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object00000000917e3491: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object00000000c0e33738: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object000000001755ddd1: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6bQuoted 9 lines
After:
Object 00000000: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object 00000010: 63 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object 00000020: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Object 00000030: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b a5I think it might be worth to convert all
DUMP_PREFIX_ADDRESStoDUMP_PREFIX_OFFSETfor the whole Linux kernel.
Quoted 5 lines
I agree it looks nicer for poisoning, I'm not sure that every caller of
print_section()is the same, however. For exampletrace()seems better off asDUMP_PREFIX_ADDRESSsince it already specifies the address of the object being allocated or freed and offset here wouldn't really be useful, no?
Thanks for the reply. I agree not all caller of print_section() is the same case. Converting all of them is not a good idea.
For mm/slub.c, let me explain with the following example.
The offset is useful for use-after-free debugging. I often trace the "free track" and find the data structure used and compare the data structure with the offset of the incorrect poison value and see if the incorrect poison value matches some member of that data structure.
Assume we have a data structure "something" and it has a member called "m", offset = 780.
struct something *p; // sizeof(struct something) is 1024
p = kmalloc(sizeof(struct something), GFP_KERNEL);
kfree(p);
(p->m) = 'c'; // assume p->member is at offset=780When we see the log: (using DUMP_PREFIX_ADDRESS)
We have to "count" the offset.
INFO: Slab 0x(____ptrval____) objects=21 used=21 fp=0x(____ptrval____) flags=0x10200
INFO: Object 0x(____ptrval____) @offset=7808 fp=0x(____ptrval____)
Redzone ____ptrval____: bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb ................
Redzone ____ptrval____: bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb ................
Redzone ____ptrval____: bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb ................
Redzone ____ptrval____: bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb ................
Redzone ____ptrval____: bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb ................
Redzone ____ptrval____: bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb ................
Redzone ____ptrval____: bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb ................
Redzone ____ptrval____: bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb ................
Object ____ptrval____: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object ____ptrval____: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object ____ptrval____: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object ____ptrval____: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object ____ptrval____: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object ____ptrval____: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object ____ptrval____: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
...
Object ____ptrval____: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object ____ptrval____: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object ____ptrval____: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object ____ptrval____: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object ____ptrval____: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object ____ptrval____: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object ____ptrval____: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object ____ptrval____: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object ____ptrval____: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object ____ptrval____: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 63 6b 6b 6b kkkkkkkkkkkkckkk
Object ____ptrval____: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object ____ptrval____: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object ____ptrval____: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object ____ptrval____: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object ____ptrval____: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object ____ptrval____: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
The log of using DUMP_PREFIX_OFFSET:
We still have to "count", but it is easier.
INFO: Slab 0x(____ptrval____) objects=21 used=21 fp=0x(____ptrval____) flags=0x10200
INFO: Object 0x(____ptrval____) @offset=7808 fp=0x(____ptrval____)
Redzone 00000000: bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb ................
Redzone 00000010: bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb ................
Redzone 00000020: bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb ................
Redzone 00000030: bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb ................
Redzone 00000040: bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb ................
Redzone 00000050: bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb ................
Redzone 00000060: bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb ................
Redzone 00000070: bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb ................
Object 00000000: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object 00000010: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object 00000020: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object 00000030: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object 00000040: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object 00000050: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object 00000060: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
...
Object 00000270: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object 00000280: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object 00000290: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object 000002a0: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object 000002b0: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object 000002c0: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object 000002d0: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object 000002e0: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object 000002f0: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object 00000300: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 63 6b 6b 6b kkkkkkkkkkkkckkk
Object 00000310: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object 00000320: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object 00000330: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object 00000340: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object 00000350: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object 00000360: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object 00000370: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Object 00000380: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
cheers,
Miles