In C#,I have an object say Shape which has two fields area and length.
I got a shapeList which is a collection of Shapes.
I have got a shapeList address in my crash dump.
I need a script in windbg that iterates through each item in the shapeList array and display the value of area alone for each shape.
.for ( r $t1 = 0; #$t1 < [length] * [element size]; r $t1 = #$t1 + [element size];) {!do poi(poi(#$t1+poi([address of list]+0x8)+0x18)+[offset of child object in parent object) }
For example:
class Foo
{
public Bar MyBar { get; set; }
}
class Bar
{
public String MyString { get; set; }
}
0:000> .for ( r $t1 = 0; #$t1 < 0x5 * 0x8; r $t1 = #$t1 + 0x8;) {!do poi(poi(#$t1+poi(0000000002362e40+0x8)+0x18)+0x8) }
Name: testdebug.Bar
MethodTable: 000007fe95eb3928
EEClass: 000007fe95fc22d8
Size: 24(0x18) bytes
File: C:\users\testdebug.exe
Fields:
MT Field Offset Type VT Attr Value Name
000007fef47b4130 4000002 8 System.String 0 instance 00000000023653b0 <MyString>k__BackingField
Name: testdebug.Bar
MethodTable: 000007fe95eb3928
EEClass: 000007fe95fc22d8
Size: 24(0x18) bytes
File: C:\users\testdebug.exe
Fields:
MT Field Offset Type VT Attr Value Name
000007fef47b4130 4000002 8 System.String 0 instance 0000000002365468 <MyString>k__BackingField
Name: testdebug.Bar
MethodTable: 000007fe95eb3928
EEClass: 000007fe95fc22d8
Size: 24(0x18) bytes
File: C:\users\testdebug.exe
Fields:
MT Field Offset Type VT Attr Value Name
000007fef47b4130 4000002 8 System.String 0 instance 0000000002365520 <MyString>k__BackingField
Name: testdebug.Bar
MethodTable: 000007fe95eb3928
EEClass: 000007fe95fc22d8
Size: 24(0x18) bytes
File: C:\users\testdebug.exe
Fields:
MT Field Offset Type VT Attr Value Name
000007fef47b4130 4000002 8 System.String 0 instance 00000000023655d8 <MyString>k__BackingField
Name: testdebug.Bar
MethodTable: 000007fe95eb3928
EEClass: 000007fe95fc22d8
Size: 24(0x18) bytes
File: C:\users\testdebug.exe
Fields:
MT Field Offset Type VT Attr Value Name
000007fef47b4130 4000002 8 System.String 0 instance 0000000002365690 <MyString>k__BackingField
Related
const myObjectId = ObjectId("507c7f79bcf86cd7994f6c0e")
const myObjectIdString = myObjectId.toString()
myObjectId has a size of 12 bytes. But what about the size of myObjectIdString?
This ObjectId is a 24-character hexadecimal string representation and when it's represented as a string it's 24 bytes.
I'm trying to read bare Data into a Swift 4 struct using the withUnsafeBytes method. The problem
The network UDP packet has this format:
data: 0102 0A00 0000 0B00 0000
01 : 1 byte : majorVersion (decimal 01)
02 : 1 byte : minorVersion (decimal 02)
0A00 0000 : 4 bytes: applicationHostId (decimal 10)
0B00 0000 : 4 bytes: versionNumber (decimal 11)
Then I have an extension on Data that takes a start and the length of bytes to read
extension Data {
func scanValue<T>(start: Int, length: Int) -> T {
return self.subdata(in: start..<start+length).withUnsafeBytes { $0.pointee }
}
}
This works correctly when reading the values one by one:
// correctly read as decimal "1"
let majorVersion: UInt8 = data.scanValue(start: 0, length: 1)
// correctly read as decimal "2"
let minorVersion: UInt8 = data.scanValue(start: 1, length: 1)
// correctly read as decimal "10"
let applicationHostId: UInt32 = data.scanValue(start: 2, length: 4)
// correctly read as decimal "11"
let versionNumber: UInt32 = data.scanValue(start: 6, length: 4)
Then I created a struct that represents the entire packet as follows
struct XPLBeacon {
var majorVersion: UInt8 // 1 Byte
var minorVersion: UInt8 // 1 Byte
var applicationHostId: UInt32 // 4 Bytes
var versionNumber: UInt32 // 4 Bytes
}
But when I read the data directly into the structure I have some issues:
var beacon: XPLBeacon = data.scanValue(start: 0, length: data.count)
// correctly read as decimal "1"
beacon.majorVersion
// correctly read as decimal "2"
beacon.minorVersion
// not correctly read
beacon.applicationHostId
// not correctly read
beacon.versionNumber
I it supposed to work to parse an entire struct like this?
Reading the entire structure from the data does not work because
the struct members are padded to their natural boundary. The
memory layout of struct XPLBeacon is
A B x x C C C C D D D D
where
offset member
0 A - majorVersion (UInt8)
1 B - minorVersion (UInt8)
2 x x - padding
4 C C C C - applicationHostId (UInt32)
8 D D D D - versionNumber (UInt32)
and the padding is inserted so that the UInt32 members are
aligned to memory addresses which are a multiple of their size. This is
also confirmed by
print(MemoryLayout<XPLBeacon>.size) // 12
(For more information about alignment in Swift, see
Type Layout).
If you read the entire data into the struct then the bytes are assigned
as follows
01 02 0A 00 00 00 0B 00 00 00
A B x x C C C C D D D D
which explains why major/minorVersion are correct, but applicationHostId and versionNumber
are wrong. Reading all members separately from the data is the correct solution.
Since Swift 3 Data conforms to RandomAccessCollection, MutableCollection, RangeReplaceableCollection. So you can simply create a custom initializer to initialise your struct properties as follow:
struct XPLBeacon {
let majorVersion, minorVersion: UInt8 // 1 + 1 = 2 Bytes
let applicationHostId, versionNumber: UInt32 // 4 + 4 = 8 Bytes
init(data: Data) {
self.majorVersion = data[0]
self.minorVersion = data[1]
self.applicationHostId = data
.subdata(in: 2..<6)
.withUnsafeBytes { $0.load(as: UInt32.self) }
self.versionNumber = data
.subdata(in: 6..<10)
.withUnsafeBytes { $0.load(as: UInt32.self) }
}
}
var data = Data([0x01,0x02, 0x0A, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00,0x00])
print(data as NSData) // "{length = 10, bytes = 0x01020a0000000b000000}\n" <01020a00 00000b00 0000>
let beacon = XPLBeacon(data: data)
beacon.majorVersion // 1
beacon.minorVersion // 2
beacon.applicationHostId // 10
beacon.versionNumber // 11
Following on Leo Dabus answer, I created a slightly more readable constructor:
extension Data {
func object<T>(at index: Index) -> T {
subdata(in: index ..< index.advanced(by: MemoryLayout<T>.size))
.withUnsafeBytes { $0.load(as: T.self) }
}
}
struct XPLBeacon {
var majorVersion: UInt8
var minorVersion: UInt8
var applicationHostId: UInt32
var versionNumber: UInt32
init(data: Data) {
var index = data.startIndex
majorVersion = data.object(at: index)
index += MemoryLayout.size(ofValue: majorVersion)
minorVersion = data.object(at: index)
index += MemoryLayout.size(ofValue: minorVersion)
applicationHostId = data.object(at: index)
index += MemoryLayout.size(ofValue: applicationHostId)
versionNumber = data.object(at: index)
}
}
What is not part of this is of course the checking for the correctness of the data. As other mentioned in comments, this could be done either by having a failable init method or by throwing an Error.
There is a new class. Each instance contain a refernce to next instance.
The goal is to build __repr__(self) function, that represent element of the class with all referenced elements, when each value wrapped by defined symbol. For example by # or *.
Something like this:
****** ****** ******
* 10 * * 20 * * 30 *
****** ****** ******
There is an example:
class Node:
def __init__(self, value):
self.value = value
self.pointer = None
#pointer.setter
def pointer(self, next_node):
self.pointer = next_node
p1 = Node(10)
p2 = Node(20)
p3 = Node(30)
p1.pointer = p2
p2.pointer = p3
print (p1)
That what I did:
def __str__(self):
ans = "{1} {0} {1}".format(self.value, "*")
wrap = "{0:{1}^{2}}".format("", "*", len(ans))
return "{1}\n* {0} *\n{1}".format(ans, wrap)
But it works only for one element.
For printing of all referenced elements i wrote another function:
def show(self):
buf = self
while buf.value:
print(buf)
if buf.pointer:
buf = buf.pointer
else:
break
But it prints each element on a new line. Like this:
******
* 10 *
******
******
* 20 *
******
******
* 30 *
******
The problem is that i don't know how return on first line with some indent and print the next 3 lines elemen.
The question:
Is there some way to build __repr__() function for representing all referenced elements?
That's I have done... Forgive me for this huge code. I am just pretty new in python.
I solved it by .format() funtion. And by printing 3 lines at the output. But i still wait and hope for more elegant solution...
There is also option to change the wrapping character in print_linked_list fuction. And it prints only 5 following values.
def __repr__(self):
return self.print_linked_list()
__str__ = __repr__
def print_linked_list(self, border="*", count=5):
# examples of printing:
# ***** ****** ******* ****** *****
# * 3 * -> * 80 * -> * 100 * -> * 20 * -> * 8 *
# ***** ****** ******* ****** *****
ar = " -> "
wrap, ans_string = str(), str()
buf = self
while buf and count >= 0:
ans = "{0} {1} {0}".format(border, buf.value)
ans_string += ans + (ar if buf.next else "")
wrap += "{0:{1}<{2}}".format("", border, len(ans)) + \
"{:^{}}".format("", len(ar))
buf = buf.next if buf.next else False
count -= 1
return "\n{0}\n{1}\n{0}".format(wrap, ans_string)
I have a FixMessage and I want to calculate the checksum manually.
8=FIX.4.2|9=49|35=5|34=1|49=ARCA|52=20150916-04:14:05.306|56=TW|10=157|
The body length here is calculated:
8=FIX.4.2|9=49|35=5|34=1|49=ARCA|52=20150916-04:14:05.306|56=TW|10=157|
0 + 0 + 5 + 5 + 8 + 26 + 5 + 0 = 49(correct)
The checksum is 157 (10=157). How to calculate it in this case?
You need to sum every byte in the message up to but not including the checksum field. Then take this number modulo 256, and print it as a number of 3 characters with leading zeroes (e.g. checksum=13 would become 013).
Link from the FIX wiki: FIX checksum
An example implementation in C, taken from onixs.biz:
char *GenerateCheckSum( char *buf, long bufLen )
{
static char tmpBuf[ 4 ];
long idx;
unsigned int cks;
for( idx = 0L, cks = 0; idx < bufLen; cks += (unsigned int)buf[ idx++ ] );
sprintf( tmpBuf, "%03d", (unsigned int)( cks % 256 ) );
return( tmpBuf );
}
Ready-to-run C example adapted from here
8=FIX.4.2|9=49|35=5|34=1|49=ARCA|52=20150916-04:14:05.306|56=TW|10=157|
#include <stdio.h>
void GenerateCheckSum( char *buf, long bufLen )
{
unsigned sum = 0;
long i;
for( i = 0L; i < bufLen; i++ )
{
unsigned val = (unsigned)buf[i];
sum += val;
printf("Char: %02c Val: %3u\n", buf[i], val); // print value of each byte
}
printf("CheckSum = %03d\n", (unsigned)( sum % 256 ) ); // print result
}
int main()
{
char msg[] = "8=FIX.4.2\0019=49\00135=5\00134=1\00149=ARCA\00152=20150916-04:14:05.306\00156=TW\001";
int len = sizeof(msg) / sizeof(msg[0]);
GenerateCheckSum(msg, len);
}
Points to Note
GenerateCheckSum takes the entire FIX message except CheckSum field
Delimiter SOH is written as \001 which has ASCII value 1
static void Main(string[] args)
{
//10=157
string s = "8=FIX.4.2|9=49|35=5|34=1|49=ARCA|52=20150916-04:14:05.306|56=TW|";
byte[] bs = GetBytes(s);
int sum=0;
foreach (byte b in bs)
sum = sum + b;
int checksum = sum % 256;
}
//string to byte[]
static byte[] GetBytes(string str)
{
byte[] bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
Using BodyLength[9] and CheckSum[10] fields.
BodyLength is calculated starting from field starting after BodyLenght and
before CheckSum field.
CheckSum is calculated from ‘8= upto SOH before the checksum field.
Binary value of each character is calculated and compared to the LSB of the calculated value to the checksum value.
If the checksum has been calculated to be 274 then the modulo 256 value is 18 (256 + 18 = 274). This value would be transmitted a 10=018 where
"10="is the tag for the checksum field.
In Java there is a method from QuickFixJ.
String fixStringMessage = "8=FIX.4.29=12535=81=6090706=011=014=017=020=322=837=038=4.39=054=155=ALFAA99=20220829150=0151=06020=06021=06022=F9014=Y";
int checkSum = quickfix.MessageUtils.checksum(fixStringMessage);
System.out.prinln(checkSum);
Output: 127
Hope it can help you.
I referred this SO Answer for creating variadic function in objective C.
I tested your code by passing arguments like below:
[self logMessage:#"string: %#\n number: %#\n image: %#",
#"asdf",
[NSNumber numberWithInt:23],
[UIImage imageNamed:#"local.png"]];
and edited the code with NSLog();
- (void)logMessage:(NSString *)format, ... {
va_list args;
va_start(args, format);
id arg = nil;
int i = 1;
NSLogv(format, args);
while ((arg = va_arg(args,NSString *))) {
NSLog(#"val: %d", i++);
/// Do your thing with arg here
//NSString *name = NSStringFromClass([arg class]);
//NSLog(#"string: %#", name);
}
va_end(args);
}
But the output as follows:
2012-09-28 19:34:45.271 SIMO[2384:c07] string: asdf
number: 23
image: <UIImage: 0x8151f80>
2012-09-28 19:34:45.273 SIMO[2384:c07] val: 1
2012-09-28 19:34:45.273 SIMO[2384:c07] val: 2
2012-09-28 19:34:45.274 SIMO[2384:c07] val: 3
2012-09-28 19:34:45.274 SIMO[2384:c07] val: 4
2012-09-28 19:34:45.274 SIMO[2384:c07] val: 5
2012-09-28 19:34:45.275 SIMO[2384:c07] val: 6
2012-09-28 19:34:45.275 SIMO[2384:c07] val: 7
2012-09-28 19:34:45.276 SIMO[2384:c07] val: 8
This tells that the argument is 8, but I passed only 3 (NSString, NSNumber, UIImage)
I can't get the concept.. Could you clarify me
Could anyone clarify this
va_arg doesn't really know when the argument list ends. The approach you're using expects the argument list to be terminated by nil, like +[NSArray arrayWithObjects:].
So either change your invocation to add nil at the end of the argument list, or find some other way of knowing when the arguments are over (e.g. for a printf clone, you might know the number of format arguments from the format string itself).