initialize a USB device from pywinusb / python - python-2.7
my problem lokks like the one suggested by Will "Simple reading/writing from/to a USB HID device in Python?", but following it I did not get any result. Problem: I am trying to handle the Oregon WMRS200 Meteo station, that implements a usb connection as a HID device. I started adapting/simplifying the example provided 'raw data.py' as listed below
from time import sleep
from msvcrt import kbhit
import pywinusb.hid as hid
def sample_handler(data):
print("Raw data: {0}".format(data))
def raw_test():
device = (hid.HidDeviceFilter (vendor_id =0x0fde , product_id = 0xca01). \
get_devices())[0]
device.open()
#set custom raw data handler
device.set_raw_data_handler(sample_handler)
print("\nWaiting for data...\nPress any (system keyboard) key to stop...")
while not kbhit() and device.is_plugged():
#just keep the device opened to receive events
sleep(0.5)
device.close()
return
if __name__ == '__main__':
raw_test()
the transfer of the data does not start. I find on the net that the system must be initialized once (after a reset or pw failure) sending a buffer
0x20 0x00 0x08 0x01 0x00 0x00 0x00 0x00
The problem is that I do not know how to send it. doing something like sending a report (as in the example quoted above) dows not get any result.
If after a reset I start and stop once the original oregon sw everything starts working, i.e. the channel is somehow initialized. Installing a sniffer on the communication channel I think I see the byte string going to the device, but still, how can I send it ??
Here is the output of the sniffer with the original sw. I suppose that the byte pattern may be seen in the URB 9-10 going to the device.
[229 ms] >>> URB 1 going down >>>
-- URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
TransferBufferLength = 00000012
DescriptorType = 00000001 (USB_DEVICE_DESCRIPTOR_TYPE)
[234 ms] <<< URB 1 coming back <<<
-- URB_FUNCTION_CONTROL_TRANSFER:
TransferFlags = 0000000b (USBD_TRANSFER_DIRECTION_IN, USBD_SHORT_TRANSFER_OK)
TransferBufferLength = 00000012
00000000: 12 01 10 01 00 00 00 08 de 0f 01 ca 02 03 00 01
00000010: 00 01
SetupPacket =
00000000: 80 06 00 01 00 00 12 00
[234 ms] >>> URB 2 going down >>>
-- URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
TransferBufferLength = 00000009
DescriptorType = 00000002 (USB_CONFIGURATION_DESCRIPTOR_TYPE)
[239 ms] <<< URB 2 coming back <<<
-- URB_FUNCTION_CONTROL_TRANSFER:
TransferFlags = 0000000b (USBD_TRANSFER_DIRECTION_IN, USBD_SHORT_TRANSFER_OK)
TransferBufferLength = 00000009
00000000: 09 02 22 00 01 01 00 80 32
SetupPacket =
00000000: 80 06 00 02 00 00 09 00
[239 ms] >>> URB 3 going down >>>
-- URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
TransferBufferLength = 00000022
DescriptorType = 00000002 (USB_CONFIGURATION_DESCRIPTOR_TYPE)
[247 ms] <<< URB 3 coming back <<<
-- URB_FUNCTION_CONTROL_TRANSFER:
TransferFlags = 0000000b (USBD_TRANSFER_DIRECTION_IN, USBD_SHORT_TRANSFER_OK)
TransferBufferLength = 00000022
00000000: 09 02 22 00 01 01 00 80 32 09 04 00 00 01 03 00
00000010: 00 00 09 21 10 01 00 01 22 22 00 07 05 81 03 08
00000020: 00 01
SetupPacket =
00000000: 80 06 00 02 00 00 22 00
[247 ms] >>> URB 4 going down >>>
-- URB_FUNCTION_SELECT_CONFIGURATION:
ConfigurationDescriptor = 0x899fb730 (configure)
ConfigurationDescriptor : bLength = 9
ConfigurationDescriptor : bDescriptorType = 0x00000002
ConfigurationDescriptor : wTotalLength = 0x00000022
ConfigurationDescriptor : bNumInterfaces = 0x00000001
ConfigurationDescriptor : bConfigurationValue = 0x00000001
ConfigurationDescriptor : iConfiguration = 0x00000000
ConfigurationDescriptor : bmAttributes = 0x00000080
ConfigurationDescriptor : MaxPower = 0x00000032
ConfigurationHandle = 0x00000000
Interface[0]: Length = 36
Interface[0]: InterfaceNumber = 0
Interface[0]: AlternateSetting = 0
[280 ms] <<< URB 4 coming back <<<
-- URB_FUNCTION_SELECT_CONFIGURATION:
ConfigurationDescriptor = 0x899fb730 (configure)
ConfigurationDescriptor : bLength = 9
ConfigurationDescriptor : bDescriptorType = 0x00000002
ConfigurationDescriptor : wTotalLength = 0x00000022
ConfigurationDescriptor : bNumInterfaces = 0x00000001
ConfigurationDescriptor : bConfigurationValue = 0x00000001
ConfigurationDescriptor : iConfiguration = 0x00000000
ConfigurationDescriptor : bmAttributes = 0x00000080
ConfigurationDescriptor : MaxPower = 0x00000032
ConfigurationHandle = 0x89a11ab8
Interface[0]: Length = 36
Interface[0]: InterfaceNumber = 0
Interface[0]: AlternateSetting = 0
Interface[0]: Class = 0x00000003
Interface[0]: SubClass = 0x00000000
Interface[0]: Protocol = 0x00000000
Interface[0]: InterfaceHandle = 0x8a2a18b0
Interface[0]: NumberOfPipes = 1
Interface[0]: Pipes[0] : MaximumPacketSize = 0x00000008
Interface[0]: Pipes[0] : EndpointAddress = 0x00000081
Interface[0]: Pipes[0] : Interval = 0x00000001
Interface[0]: Pipes[0] : PipeType = 0x00000003 (UsbdPipeTypeInterrupt)
Interface[0]: Pipes[0] : PipeHandle = 0x8a2a18cc
Interface[0]: Pipes[0] : MaxTransferSize = 0x00001000
Interface[0]: Pipes[0] : PipeFlags = 0x00000000
[280 ms] >>> URB 5 going down >>>
-- URB_FUNCTION_CLASS_INTERFACE:
TransferFlags = 00000000 (USBD_TRANSFER_DIRECTION_OUT, USBD_SHORT_TRANSFER_OK)
TransferBufferLength = 00000000
no data supplied
RequestTypeReservedBits = 00000022
Request = 0000000a
Value = 00000000
Index = 00000000
[282 ms] <<< URB 5 coming back <<<
-- URB_FUNCTION_CONTROL_TRANSFER:
TransferFlags = 0000000a (USBD_TRANSFER_DIRECTION_OUT, USBD_SHORT_TRANSFER_OK)
TransferBufferLength = 00000000
SetupPacket =
00000000: 21 0a 00 00 00 00 00 00
[282 ms] >>> URB 6 going down >>>
-- URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE:
TransferBufferLength = 00000062
DescriptorType = 00000022 (<illegal descriptor type!>)
[291 ms] <<< URB 6 coming back <<<
-- URB_FUNCTION_CONTROL_TRANSFER:
PipeHandle = 8a2a4198
TransferFlags = 0000000b (USBD_TRANSFER_DIRECTION_IN, USBD_SHORT_TRANSFER_OK)
TransferBufferLength = 00000022
00000000: 06 00 ff 09 01 a1 01 09 01 15 00 26 ff 00 75 08
00000010: 95 08 81 00 09 02 15 00 26 ff 00 75 08 95 08 91
00000020: 02 c0
SetupPacket =
00000000: 81 06 00 22 00 00 62 00
[294 ms] >>> URB 7 going down >>>
-- URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
TransferFlags = 00000003 (USBD_TRANSFER_DIRECTION_IN, USBD_SHORT_TRANSFER_OK)
TransferBufferLength = 00000008
[294 ms] >>> URB 8 going down >>>
-- URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
TransferFlags = 00000003 (USBD_TRANSFER_DIRECTION_IN, USBD_SHORT_TRANSFER_OK)
TransferBufferLength = 00000008
[3330 ms] <<< URB 7 coming back <<<
-- URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
TransferFlags = 00000003 (USBD_TRANSFER_DIRECTION_IN, USBD_SHORT_TRANSFER_OK)
TransferBufferLength = 00000008
00000000: 01 ff 01 cc 01 87 01 00
[3330 ms] >>> URB 9 going down >>>
-- URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
TransferFlags = 00000003 (USBD_TRANSFER_DIRECTION_IN, USBD_SHORT_TRANSFER_OK)
TransferBufferLength = 00000008
[3330 ms] >>> URB 10 going down >>>
-- URB_FUNCTION_CLASS_INTERFACE:
TransferFlags = 00000000
(USBD_TRANSFER_DIRECTION_OUT, ~USBD_SHORT_TRANSFER_OK)
TransferBufferLength = 00000008
00000000: 20 00 08 01 00 4d 80 00
RequestTypeReservedBits = 00000022
Request = 00000009
Value = 00000200
Index = 00000000
From URB 11 - --> the normal transfer starts also with my example script.
I hope I have been sufficiently clear ..... Thanks for any help.
For sending RAW data (no HID descriptor managed reports), you can use the "device.send_output_report()", pass any list as a parameter (or for better performance, you can pass a ctypes.c_ubyte array.
Related
How to debug further for ntdll!RtlDeactivateActivationContextUnsafeFast?
I am getting below call stack when debugging one of the crash dump which I got, How to debug further for this call stack ntdll!RtlDeactivateActivationContextUnsafeFast? # ChildEBP RetAddr Args to Child 00 002ceb10 76656d91 76682875 7668279d 002ceba0 ntdll!RtlDeactivateActivationContextUnsafeFast+0x209 01 002ceb14 76682875 7668279d 002ceba0 766827ad user32!UserCallWinProcCheckWow+0x13d 02 002ceb18 7668279d 002ceba0 766827ad a837dcf5 user32!_NLG_Return2 03 002ceb44 7668284d 766c0720 002cf934 fffffffe user32!_local_unwind4+0x80 04 002ceb58 766ba834 002cf944 766c0720 00000000 user32!_EH4_LocalUnwind+0x10 05 002ceb88 779133dd 002cebf8 002cf934 002ceca4 user32!_except_handler4+0x14f 06 002cebac 779133af 002cebf8 002cf934 002ceca4 ntdll!ExecuteHandler2+0x26 07 002cebd0 77913756 002cebf8 002cf934 002ceca4 ntdll!ExecuteHandler+0x24 08 002cef74 77923a9f 002cfacc 77923a9f 00000000 ntdll!RtlUnwind+0x147 09 002cef98 7792392b 00000000 00000000 00000000 ntdll!_EH4_GlobalUnwind+0x15 0a 002cefc0 779133dd fffffffe 002cfacc 002cf0fc ntdll!_except_handler4+0xe7 0b 002cefe4 779133af 002cf0ac 002cfacc 002cf0fc ntdll!ExecuteHandler2+0x26 0c 002cf008 77913350 002cf0ac 002cfacc 002cf0fc ntdll!ExecuteHandler+0x24 0d 002cf094 778c0133 002cf0ac 002cf0fc 002cf0ac ntdll!RtlDispatchException+0x127 0e 002cf094 77933f11 002cf0ac 002cf0fc 002cf0ac ntdll!KiUserExceptionDispatcher+0xf 0f 002cf5bc 7501544c 005707d0 14af5e6e 002cf614 ntdll!RtlDeactivateActivationContext+0x154 10 002cf5cc 547a9882 00000000 14af5e6e 05da3699 kernel32!DeactivateActCtx+0x31 11 002cf5d8 05da3699 a86ae6b6 054cadd0 0102f9a0 **mfc100u!AFX_MAINTAIN_STATE2::~AFX_MAINTAIN_STATE2+0x1d** 12 002cf614 0102fac1 00000000 00000040 00000000 **Mylib!MyClass::MyFunct**+0x79 14 002cf778 548b4b4c 00000511 00000040 00069000 mfc100u!CWnd::OnWndMsg+0x2f5 15 002cf798 53fbd53b 00000511 00000040 00069000 mfc100u!CWnd::WindowProc+0x24
C++ Converting string packet to iphdr - what should be the format of string packet?
So I have this line of code: struct iphdr *ip_header = (struct iphdr*) packet.c_str(); from ip.h: struct iphdr { #if __BYTE_ORDER == __LITTLE_ENDIAN unsigned int ihl:4; unsigned int version:4; #elif __BYTE_ORDER == __BIG_ENDIAN unsigned int version:4; unsigned int ihl:4; #else # error "Please fix <bits/endian.h>" #endif u_int8_t tos; u_int16_t tot_len; u_int16_t id; u_int16_t frag_off; u_int8_t ttl; u_int8_t protocol; u_int16_t check; u_int32_t saddr; u_int32_t daddr; /*The options start here. */ }; I captured a DNS packet using wireshark and I got this sample packet: 0000 e0 8e 3c 1c c0 07 ac bc 32 83 84 d9 08 00 45 00 0010 00 3f 51 45 00 00 40 11 aa b3 c0 a8 fe 65 c0 a8 0020 fe fe 0e 76 00 35 00 2b d5 1c 9c 0a 01 00 00 01 0030 00 00 00 00 00 00 03 77 77 77 06 67 6f 6f 67 6c 0040 65 03 63 6f 6d 02 70 68 00 00 01 00 01 I removed the eth header and so I'm left with this: 0000 45 00 0010 00 3f 51 45 00 00 40 11 aa b3 c0 a8 fe 65 c0 a8 0020 fe fe 0e 76 00 35 00 2b d5 1c 9c 0a 01 00 00 01 0030 00 00 00 00 00 00 03 77 77 77 06 67 6f 6f 67 6c 0040 65 03 63 6f 6d 02 70 68 00 00 01 00 01 The first part (45 00 00 3f 51 45 00 00 40 11) translates to this: 45 0100 .... = Version: 4 .... 0101 = Header Length: 20 bytes (5) 00 Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT) 00 3f Total Length: 63 51 45 Identification: 0x5145 (20805) 00 00 Flags: 0x00 Fragment offset: 0 40 Time to live: 64 11 Protocol: UDP (17) My question is: what should be the format of the string variable packet? I have tried this: std::string packet = "45 00 00 3f 51 45 00 00 40 11"; but for ip_header->protocol I get 48 '0' instead of 17. Also I'm wondering, why is the protocol not on the 9th byte? I was assuming it should be on the 9th based on the structure of iphdr. Would highly appreciate anyone's help. Thanks a lot!
Your basic assumption has some problems. You're using a string and you assume that if you cast it to some structure definition it will automatically (and auto-magically) convert it to the proper binary representation of that structure definition. This is not the case. Let's say you have a structure 'struct Test { unsigned int t; }' and a string 'std::string st = "12"'. And you do 'struct Test *pt = st.c_str();'. The ASCII representation of "12" would be 0x31 0x32 so now *pt points to a memory location starting with 31 32. Casting this to in integer (assume we have a big-endian system and assume the unsigned int is two bytes) results in 0x3132 (decimal 12594).
Where Are Relocation Entries Stored in Flat Binaries?
Please be attend to the following example. I have a C++ code that I want to compile under powerpc and generate the binary code. #include <stdio.h> int function(int x); int myfunction(int x); int main() { int x = function(2); int y = myfunction(2); return x + y; } int function(int x) { return x * myfunction(x); } int myfunction(int x) { return x; } I have two function calls: call function(2) and call myfunction(2). I compile this C++ code under powerpc. So, now I use the objdump to get the assembly behind the object file and that is as follows: 00000000 <main>: 0: 94 21 ff e0 stwu r1,-32(r1) 4: 7c 08 02 a6 mflr r0 8: 93 e1 00 1c stw r31,28(r1) c: 90 01 00 24 stw r0,36(r1) 10: 7c 3f 0b 78 mr r31,r1 14: 38 60 00 02 li r3,2 18: 48 00 00 01 bl 18 <main+0x18> 1c: 7c 60 1b 78 mr r0,r3 20: 90 1f 00 08 stw r0,8(r31) 24: 38 60 00 02 li r3,2 28: 48 00 00 01 bl 28 <main+0x28> 2c: 7c 60 1b 78 mr r0,r3 30: 90 1f 00 0c stw r0,12(r31) 34: 80 1f 00 08 lwz r0,8(r31) 38: 81 3f 00 0c lwz r9,12(r31) 3c: 7c 00 4a 14 add r0,r0,r9 40: 7c 03 03 78 mr r3,r0 44: 48 00 00 0c b 50 <main+0x50> 48: 38 60 00 00 li r3,0 4c: 48 00 00 04 b 50 <main+0x50> 50: 81 61 00 00 lwz r11,0(r1) 54: 80 0b 00 04 lwz r0,4(r11) 58: 7c 08 03 a6 mtlr r0 5c: 83 eb ff fc lwz r31,-4(r11) 60: 7d 61 5b 78 mr r1,r11 64: 4e 80 00 20 blr 00000068 <function__Fi>: 68: 94 21 ff e0 stwu r1,-32(r1) 6c: 7c 08 02 a6 mflr r0 70: 93 e1 00 1c stw r31,28(r1) 74: 90 01 00 24 stw r0,36(r1) 78: 7c 3f 0b 78 mr r31,r1 7c: 90 7f 00 08 stw r3,8(r31) 80: 80 7f 00 08 lwz r3,8(r31) 84: 48 00 00 01 bl 84 <function__Fi+0x1c> 88: 7c 60 1b 78 mr r0,r3 8c: 81 3f 00 08 lwz r9,8(r31) 90: 7c 00 49 d6 mullw r0,r0,r9 94: 7c 03 03 78 mr r3,r0 98: 48 00 00 0c b a4 <function__Fi+0x3c> 9c: 48 00 00 08 b a4 <function__Fi+0x3c> a0: 48 00 00 04 b a4 <function__Fi+0x3c> a4: 81 61 00 00 lwz r11,0(r1) a8: 80 0b 00 04 lwz r0,4(r11) ac: 7c 08 03 a6 mtlr r0 b0: 83 eb ff fc lwz r31,-4(r11) b4: 7d 61 5b 78 mr r1,r11 b8: 4e 80 00 20 blr 000000bc <myfunction__Fi>: bc: 94 21 ff e0 stwu r1,-32(r1) c0: 93 e1 00 1c stw r31,28(r1) c4: 7c 3f 0b 78 mr r31,r1 c8: 90 7f 00 08 stw r3,8(r31) cc: 80 1f 00 08 lwz r0,8(r31) d0: 7c 03 03 78 mr r3,r0 d4: 48 00 00 04 b d8 <myfunction__Fi+0x1c> d8: 81 61 00 00 lwz r11,0(r1) dc: 83 eb ff fc lwz r31,-4(r11) e0: 7d 61 5b 78 mr r1,r11 e4: 4e 80 00 20 blr The interesting thing that wondered me is the line that do function calls: 18: 48 00 00 01 bl 18 <main+0x18> ... 28: 48 00 00 01 bl 28 <main+0x28> As you see, both are the binary code "48 00 00 01", but one calls function and another calls myfunction. The problem is that how we can find the call target. As I found, the call targets are written on RELOCATION ENTRIES. Oh, everything is okay, I use the command below to generate the relocation entries and is as follows: RELOCATION RECORDS FOR [.text]: OFFSET TYPE VALUE 00000018 R_PPC_REL24 function__Fi 00000028 R_PPC_REL24 myfunction__Fi 00000084 R_PPC_REL24 myfunction__Fi This entries are useful to find the call target. Now, I use the objcopy -O binary command to generate the raw binary file (flat binary). objcopy -O binary object-file My object-file is the elf32-powerpc. The output binary file shown in following block: 2564 0000 2564 0a00 93e1 001c 9001 0024 7c3f 0b78 3860 0002 4800 0001 7c60 1b78 901f 0008 3860 0002 4800 0001 7c60 1b78 901f 000c 801f 0008 2c00 0002 4182 003c 2c00 0002 4181 0010 2c00 0001 4182 0014 4800 0058 2c00 0003 4182 0038 4800 004c 3d20 0000 3869 0000 389f 0008 4cc6 3182 4800 0001 4800 004c 3d20 0000 3869 0004 3880 0014 4cc6 3182 4800 0001 4800 0034 3d20 0000 3869 0004 3880 001e 4cc6 3182 4800 0001 4800 001c 3d20 0000 3869 0004 3880 0028 4cc6 3182 4800 0001 4800 0004 3860 0000 4800 0004 8161 0000 800b 0004 7c08 03a6 83eb fffc 7d61 5b78 4e80 0020 9421 ffe0 7c08 02a6 93e1 001c 9001 0024 7c3f 0b78 907f 0008 807f 0008 4800 0001 7c60 1b78 813f 0008 7c00 49d6 7c03 0378 4800 000c 4800 0008 4800 0004 8161 0000 800b 0004 7c08 03a6 83eb fffc 7d61 5b78 4e80 0020 9421 ffe0 93e1 001c 7c3f 0b78 907f 0008 801f 0008 7c03 0378 4800 0004 8161 0000 83eb fffc 7d61 5b78 4e80 0020 We can find the 4800 0001 on it. But there is no relocation entries. Could any one please tell me how can I find the relocation entries? Thanks in Advance.
Your relocation entries are discarded when you do the objcopy. From the manual: objcopy can be used to generate a raw binary file by using an output target of binary (e.g., use -O binary). When objcopy generates a raw binary file, it will essentially produce a memory dump of the contents of the input object file. All symbols and relocation information will be discarded. The memory dump will start at the load address of the lowest section copied into the output file. For your raw binary to be useful, you have a few options here: You can perform the relocations during the build process, so that your raw binary is ready to run. However, this means that the binary file needs to be run at a fixed address in memory. Alternatively, you can produce an object file that does not require relocation - all address references need to be relative. Lookup "position-independent code" for more details. Finally, you could also use some other way of generating the raw binary (instead of, or in addition to, the objcopy stage), which includes the relocation table in the output file, and then have your code manually process these relocations at runtime. The choice here will depend on what you're trying to do, and what constraints your runtime environment has.
SSL_do_handshake gets error wrong version number
I have made a programmer following this: Directly Read/Write Handshake data with Memory BIO But now the function call SSL_do_handshake gets the error wrong version number, do you have any idea? Here is the sample code. client, SSL_set_bio(pssl, rbio, wbio); SSL_set_connect_state(pssl); SSL_do_handshake(pssl); length = BIO_read(wbio, buffer, length); server, SSL_CTX_load_verify_locations(global_sslctx , "cacerts.pem" , NULL); SSL_CTX_use_certificate_file( global_sslctx , "cert.pem" , SSL_FILETYPE_PEM); SSL_CTX_use_PrivateKey_file( global_sslctx , "cert.pem" , SSL_FILETYPE_PEM); BIO_write(SSL_get_wbio(pssl) , pdata , length); if (!SSL_is_init_finished(pssl)) { SSL_do_handshake(pssl); printf("%s" ,ERR_reason_error_string(ERR_get_error())); } And i have dumped the momery data of the client, 16 03 01 00 de 01 00 00 da 03 01 9b dc 1e ef 4d f6 74 96 9b 8a 3f c0 3f de 37 4c 1b fa d7 d8 04 12 79 f9 bf 92 38 d8 59 c0 4f b4 00 00 68 c0 14 c0 0a c0 22 c0 21 00 39 00 38 00 88 00 87 c0 0f c0 05 00
How to read the model of monitor from the EDID?
In the registry there is one (or more) key depending how many monitors you have HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\DISPLAY\DEL404C{Some Unique ID}\Device Parameters\EDID which is a REG_BINARY key. In my case this is : 00 ff ff ff ff ff ff 00 4c 2d 6f 03 39 31 59 4d 07 12 01 03 0e 29 1a 78 2a 80 c5 a6 57 49 9b 23 12 50 54 bf ef 80 95 00 95 0f 81 80 81 40 71 4f 01 01 01 01 01 01 9a 29 a0 d0 51 84 22 30 50 98 36 00 ac ff 10 00 00 1c 00 00 00 fd 00 38 4b 1e 51 0e 00 0a 20 20 20 20 20 20 00 00 00 fc 00 53 79 6e 63 4d 61 73 74 65 72 0a 20 20 00 00 00 ff 00 48 56 44 51 32 30 36 37 37 37 0a 20 20 00 ef My question is how can I read only model of monitor ("SyncMaster" for example) and not all of the information using C or C++? The format of EDID is described here: http://en.wikipedia.org/wiki/Extended_display_identification_data
What you're interested in here is the descriptor blocks of the EDID, which are found in the byte ranges 54-71, 72-89, 90-107, and 108-125. Here's those four blocks in your EDID: #1: 9a29 a0d0 5184 2230 5098 3600 acff 1000 00 #2: 0000 00fd 0038 4b1e 510e 000a 2020 2020 20 #3: 0000 00fc 0053 796e 634d 6173 7465 720a 20 #4: 0000 00ff 0048 5644 5132 3036 3737 370a 00 You can identify the descriptor containing the monitor name because the first three bytes are all zero (so it isn't a detailed timing descriptor), and the fourth one byte FC (indicating the type). The fifth byte and beyond contain the name, which is here: 5379 6e63 4d61 7374 6572 0a20 SyncMaster.. So, in short: Check at offsets 54, 72, 90, and 108 for the sequence 00 00 00 FC; if you find a match, the monitor name is the next 12 bytes.