How would I go about monitoring Kernel callbacks? I am specifically interested in monitoring the callback functions from the Kernel callback table. I am trying to figure out which user32 API call triggers which callback function.
I do not believe I can see these calls using a debugger, so would an option be ETW tracing?
I did some quick tests (on Windows 10) using the kernel debugger since it's pretty much needed to get which user calls ends up in which callback function.
I'm using notepad.exe as a target since it has a GUI.
2: kd> !process 0 0 notepad.exe
PROCESS ffffb987185d9080
SessionId: 1 Cid: 20ec Peb: c21923b000 ParentCid: 141c
DirBase: 5510e002 ObjectTable: ffffa80636fcf340 HandleCount: 239.
Image: notepad.exe
the _EPROCESS structure is at 0xffffb987185d9080 and its _PEB is at 0xc21923b000. The first one will be useful to put a breakpoint just for notepad.exe and the second one to have a view on the kernel call back table.
Setting a BP on nt!KeUserModeCallback
2: kd> bp /p ffffb987185d9080 nt!KeUserModeCallback; g
We know that the first parameter for this function is an index into the kernel callback table:
NTSTATUS KeUserModeCallback (
IN ULONG ApiNumber,
IN PVOID InputBuffer,
IN ULONG InputLength,
OUT PVOID *OutputBuffer,
IN PULONG OutputLength
);
The kernel callback table is accesssible directly from the _PEB structure, using the KernelCallbackTable field:
1: kd> dt _peb c21923b000 KernelC*
wintypes!_PEB
+0x058 KernelCallbackTable : 0x00007ffc`12831070 Void
1: kd> dps 0x00007ffc`12831070
00007ffc`12831070 00007ffc`127c2710 USER32!_fnCOPYDATA
00007ffc`12831078 00007ffc`128299f0 USER32!_fnCOPYGLOBALDATA
00007ffc`12831080 00007ffc`127c0b90 USER32!_fnDWORD
00007ffc`12831088 00007ffc`127c69f0 USER32!_fnNCDESTROY
00007ffc`12831090 00007ffc`127cda60 USER32!_fnDWORDOPTINLPMSG
00007ffc`12831098 00007ffc`1282a220 USER32!_fnINOUTDRAG
00007ffc`128310a0 00007ffc`127c7f20 USER32!_fnGETTEXTLENGTHS
00007ffc`128310a8 00007ffc`12829ec0 USER32!_fnINCNTOUTSTRING
00007ffc`128310b0 00007ffc`12829f80 USER32!_fnINCNTOUTSTRINGNULL
00007ffc`128310b8 00007ffc`127c9690 USER32!_fnINLPCOMPAREITEMSTRUCT
00007ffc`128310c0 00007ffc`127c2b70 USER32!__fnINLPCREATESTRUCT
00007ffc`128310c8 00007ffc`1282a040 USER32!_fnINLPDELETEITEMSTRUCT
00007ffc`128310d0 00007ffc`127cfdf0 USER32!__fnINLPDRAWITEMSTRUCT
00007ffc`128310d8 00007ffc`1282a0a0 USER32!_fnINLPHELPINFOSTRUCT
00007ffc`128310e0 00007ffc`1282a0a0 USER32!_fnINLPHELPINFOSTRUCT
00007ffc`128310e8 00007ffc`1282a1a0 USER32!_fnINLPMDICREATESTRUCT
It's interesting to see that this table also have a symbolic name, namely USER32!apfnDispatch:
1: kd> ln 0x00007ffc`12831070
(0x00007ffc`12831070) USER32!apfnDispatch
1: kd> ? USER32!apfnDispatch
Evaluate expression: 140720619065456 = 00007ffc`12831070
With all this we can set a logging breakpoint on nt!KeUserModeCallback:
1: kd> bp /p ffffb987185d9080 nt!KeUserModeCallback ".printf \"RCX: %p --> %y\\n\", #rcx, poi(user32!apfnDispatch + (#rcx * 8)); k; g"
This prints the ApiNumber (in RCX) and the name of the function associated to the number from the kernel callback table, followed by a stack trace. Dump example:
RCX: 0000000000000016 --> USER32!_fnINOUTLPPOINT5 (00007ffc`127c3d30)
# Child-SP RetAddr Call Site
00 ffffb80f`ac76dd08 fffffe32`37a3d2ef nt!KeUserModeCallback
01 ffffb80f`ac76dd10 fffffe32`37a095d4 win32kfull!SfnINOUTLPWINDOWPOS+0x29f
02 ffffb80f`ac76de50 fffffe32`37a091c2 win32kfull!xxxSendMessageToClient+0x114
03 ffffb80f`ac76df10 fffffe32`379e0ed9 win32kfull!xxxSendTransformableMessageTimeout+0x282
04 ffffb80f`ac76e060 fffffe32`379df20c win32kfull!xxxCalcValidRects+0x32d
05 ffffb80f`ac76e200 fffffe32`379ac9c5 win32kfull!xxxEndDeferWindowPosEx+0x1ac
06 ffffb80f`ac76e2e0 fffffe32`37a25033 win32kfull!xxxProcessDesktopRecalc+0x221
07 ffffb80f`ac76e3b0 fffffe32`37a261e8 win32kfull!xxxProcessEventMessage+0x39b
08 ffffb80f`ac76e6e0 fffffe32`37a06211 win32kfull!xxxScanSysQueue+0xd48
09 ffffb80f`ac76ef20 fffffe32`37a050e2 win32kfull!xxxRealInternalGetMessage+0xef1
0a ffffb80f`ac76f3f0 fffffe32`373e6276 win32kfull!NtUserGetMessage+0x92
0b ffffb80f`ac76f480 fffff805`28c08bb5 win32k!NtUserGetMessage+0x16
0c ffffb80f`ac76f4c0 00007ffc`11b11104 nt!KiSystemServiceCopyEnd+0x25
0d 000000c2`1947fa08 00007ffc`127c1b3e win32u!NtUserGetMessage+0x14
0e 000000c2`1947fa10 00007ff6`0803c3ac USER32!GetMessageW+0x2e
0f 000000c2`1947fa70 00007ff6`080559b6 notepad!wWinMain+0x2b4
10 000000c2`1947fb20 00007ffc`131b7034 notepad!__scrt_common_main_seh+0x106
11 000000c2`1947fb60 00007ffc`14022651 KERNEL32!BaseThreadInitThunk+0x14
12 000000c2`1947fb90 00000000`00000000 ntdll!RtlUserThreadStart+0x21
RCX: 000000000000001b --> USER32!_fnINSTRING (00007ffc`127c1ce0)
# Child-SP RetAddr Call Site
00 ffffb80f`ac76dda8 fffffe32`37997895 nt!KeUserModeCallback
01 ffffb80f`ac76ddb0 fffffe32`37a095d4 win32kfull!SfnINSTRINGNULL+0x2b5
02 ffffb80f`ac76e140 fffffe32`37a091c2 win32kfull!xxxSendMessageToClient+0x114
03 ffffb80f`ac76e200 fffffe32`37a0cc10 win32kfull!xxxSendTransformableMessageTimeout+0x282
04 ffffb80f`ac76e350 fffffe32`37a24ebd win32kfull!xxxSendMessage+0x2c
05 ffffb80f`ac76e3b0 fffffe32`37a261e8 win32kfull!xxxProcessEventMessage+0x225
06 ffffb80f`ac76e6e0 fffffe32`37a06211 win32kfull!xxxScanSysQueue+0xd48
07 ffffb80f`ac76ef20 fffffe32`37a050e2 win32kfull!xxxRealInternalGetMessage+0xef1
08 ffffb80f`ac76f3f0 fffffe32`373e6276 win32kfull!NtUserGetMessage+0x92
09 ffffb80f`ac76f480 fffff805`28c08bb5 win32k!NtUserGetMessage+0x16
0a ffffb80f`ac76f4c0 00007ffc`11b11104 nt!KiSystemServiceCopyEnd+0x25
0b 000000c2`1947fa08 00007ffc`127c1b3e win32u!NtUserGetMessage+0x14
0c 000000c2`1947fa10 00007ff6`0803c3ac USER32!GetMessageW+0x2e
0d 000000c2`1947fa70 00007ff6`080559b6 notepad!wWinMain+0x2b4
0e 000000c2`1947fb20 00007ffc`131b7034 notepad!__scrt_common_main_seh+0x106
0f 000000c2`1947fb60 00007ffc`14022651 KERNEL32!BaseThreadInitThunk+0x14
10 000000c2`1947fb90 00000000`00000000 ntdll!RtlUserThreadStart+0x21
RCX: 000000000000006a --> USER32!_fnINLPUAHDRAWMENU (00007ffc`127c61b0)
# Child-SP RetAddr Call Site
00 ffffb80f`ad457888 fffffe32`37a4e22d nt!KeUserModeCallback
01 ffffb80f`ad457890 fffffe32`37a095d4 win32kfull!SfnINLPUAHDRAWMENU+0x20d
02 ffffb80f`ad4579c0 fffffe32`37a091c2 win32kfull!xxxSendMessageToClient+0x114
03 ffffb80f`ad457a80 fffffe32`37a0cc10 win32kfull!xxxSendTransformableMessageTimeout+0x282
04 ffffb80f`ad457bd0 fffffe32`379a852f win32kfull!xxxSendMessage+0x2c
05 ffffb80f`ad457c30 fffffe32`379a81b8 win32kfull!xxxSendUAHMenuMessage+0x3f
06 ffffb80f`ad457c80 fffffe32`379a6a45 win32kfull!xxxPaintMenuBar+0x174
07 ffffb80f`ad457d20 fffffe32`373e7152 win32kfull!NtUserPaintMenuBar+0xe5
08 ffffb80f`ad457d80 fffff805`28c08bb5 win32k!NtUserPaintMenuBar+0x2a
09 ffffb80f`ad457dd0 00007ffc`11b12c64 nt!KiSystemServiceCopyEnd+0x25
0a 000000c2`1947efd8 00007ffc`0f12a919 win32u!NtUserPaintMenuBar+0x14
0b 000000c2`1947efe0 00007ffc`0f1271f4 uxtheme!CThemeWnd::NcPaint+0x239
0c 000000c2`1947f130 00007ffc`0f12b809 uxtheme!OnDwpNcActivate+0x54
0d 000000c2`1947f170 00007ffc`0f12b271 uxtheme!_ThemeDefWindowProc+0x589
0e 000000c2`1947f350 00007ffc`127ac7e3 uxtheme!ThemeDefWindowProcW+0x11
0f 000000c2`1947f390 00007ff6`0803bb57 USER32!DefWindowProcW+0x1a3
10 000000c2`1947f3f0 00007ffc`127ae858 notepad!NPWndProc+0x557
11 000000c2`1947f730 00007ffc`127ae3dc USER32!UserCallWinProcCheckWow+0x2f8
12 000000c2`1947f8c0 00007ffc`127c0bc3 USER32!DispatchClientMessage+0x9c
13 000000c2`1947f920 00007ffc`14070c54 USER32!_fnDWORD+0x33
14 000000c2`1947f980 00007ffc`11b11104 ntdll!KiUserCallbackDispatcherContinue
15 000000c2`1947fa08 00007ffc`127c1b3e win32u!NtUserGetMessage+0x14
16 000000c2`1947fa10 00007ff6`0803c3ac USER32!GetMessageW+0x2e
17 000000c2`1947fa70 00007ff6`080559b6 notepad!wWinMain+0x2b4
18 000000c2`1947fb20 00007ffc`131b7034 notepad!__scrt_common_main_seh+0x106
19 000000c2`1947fb60 00007ffc`14022651 KERNEL32!BaseThreadInitThunk+0x14
1a 000000c2`1947fb90 00000000`00000000 ntdll!RtlUserThreadStart+0x21
RCX: 000000000000006b --> USER32!__fnINLPUAHDRAWMENUITEM (00007ffc`127c4190)
# Child-SP RetAddr Call Site
00 ffffb80f`ad457538 fffffe32`37a4e835 nt!KeUserModeCallback
01 ffffb80f`ad457540 fffffe32`37a095d4 win32kfull!SfnINLPUAHDRAWMENUITEM+0x255
02 ffffb80f`ad457700 fffffe32`37a091c2 win32kfull!xxxSendMessageToClient+0x114
03 ffffb80f`ad4577c0 fffffe32`37a0cc10 win32kfull!xxxSendTransformableMessageTimeout+0x282
04 ffffb80f`ad457910 fffffe32`379ab397 win32kfull!xxxSendMessage+0x2c
05 ffffb80f`ad457970 fffffe32`379ab118 win32kfull!xxxSendMenuDrawItemMessage+0x17f
06 ffffb80f`ad457ab0 fffffe32`379aaf34 win32kfull!xxxDrawMenuItem+0x130
07 ffffb80f`ad457b80 fffffe32`379a8203 win32kfull!xxxMenuDraw+0x224
08 ffffb80f`ad457c80 fffffe32`379a6a45 win32kfull!xxxPaintMenuBar+0x1bf
09 ffffb80f`ad457d20 fffffe32`373e7152 win32kfull!NtUserPaintMenuBar+0xe5
0a ffffb80f`ad457d80 fffff805`28c08bb5 win32k!NtUserPaintMenuBar+0x2a
0b ffffb80f`ad457dd0 00007ffc`11b12c64 nt!KiSystemServiceCopyEnd+0x25
0c 000000c2`1947efd8 00007ffc`0f12a919 win32u!NtUserPaintMenuBar+0x14
0d 000000c2`1947efe0 00007ffc`0f1271f4 uxtheme!CThemeWnd::NcPaint+0x239
0e 000000c2`1947f130 00007ffc`0f12b809 uxtheme!OnDwpNcActivate+0x54
0f 000000c2`1947f170 00007ffc`0f12b271 uxtheme!_ThemeDefWindowProc+0x589
10 000000c2`1947f350 00007ffc`127ac7e3 uxtheme!ThemeDefWindowProcW+0x11
11 000000c2`1947f390 00007ff6`0803bb57 USER32!DefWindowProcW+0x1a3
12 000000c2`1947f3f0 00007ffc`127ae858 notepad!NPWndProc+0x557
13 000000c2`1947f730 00007ffc`127ae3dc USER32!UserCallWinProcCheckWow+0x2f8
14 000000c2`1947f8c0 00007ffc`127c0bc3 USER32!DispatchClientMessage+0x9c
15 000000c2`1947f920 00007ffc`14070c54 USER32!_fnDWORD+0x33
16 000000c2`1947f980 00007ffc`11b11104 ntdll!KiUserCallbackDispatcherContinue
17 000000c2`1947fa08 00007ffc`127c1b3e win32u!NtUserGetMessage+0x14
18 000000c2`1947fa10 00007ff6`0803c3ac USER32!GetMessageW+0x2e
19 000000c2`1947fa70 00007ff6`080559b6 notepad!wWinMain+0x2b4
1a 000000c2`1947fb20 00007ffc`131b7034 notepad!__scrt_common_main_seh+0x106
1b 000000c2`1947fb60 00007ffc`14022651 KERNEL32!BaseThreadInitThunk+0x14
1c 000000c2`1947fb90 00000000`00000000 ntdll!RtlUserThreadStart+0x21
It get a bit more complicated if you have a function like user32!GetMessageW where the callback function depends on the argument passed to GetMessageW.
In this case you need to get back to the frame where it is called:
RCX: 000000000000001c --> USER32!__fnINDEVICECHANGE (00007ffc`127cdd70)
# Child-SP RetAddr Call Site
00 ffffb80f`ac76e8a8 fffffe32`37999cab nt!KeUserModeCallback
01 ffffb80f`ac76e8b0 fffffe32`37a095d4 win32kfull!SfnINDEVICECHANGE+0x28b
02 ffffb80f`ac76ec40 fffffe32`37a08634 win32kfull!xxxSendMessageToClient+0x114
03 ffffb80f`ac76ed00 fffffe32`37a06078 win32kfull!xxxReceiveMessage+0x3b4
04 ffffb80f`ac76ef20 fffffe32`37a050e2 win32kfull!xxxRealInternalGetMessage+0xd58
05 ffffb80f`ac76f3f0 fffffe32`373e6276 win32kfull!NtUserGetMessage+0x92
06 ffffb80f`ac76f480 fffff805`28c08bb5 win32k!NtUserGetMessage+0x16
07 ffffb80f`ac76f4c0 00007ffc`11b11104 nt!KiSystemServiceCopyEnd+0x25
08 000000c2`1947fa08 00007ffc`127c1b3e win32u!NtUserGetMessage+0x14
09 000000c2`1947fa10 00007ff6`0803c3ac USER32!GetMessageW+0x2e
0a 000000c2`1947fa70 00007ff6`080559b6 notepad!wWinMain+0x2b4
0b 000000c2`1947fb20 00007ffc`131b7034 notepad!__scrt_common_main_seh+0x106
0c 000000c2`1947fb60 00007ffc`14022651 KERNEL32!BaseThreadInitThunk+0x14
0d 000000c2`1947fb90 00000000`00000000 ntdll!RtlUserThreadStart+0x21
Le'ts get back the the frame where the function is called (frame 0xa):
1: kd> .frame /r 0xa
0a 000000c2`1947fa70 00007ff6`080559b6 notepad!wWinMain+0x2b4
rax=ffffb80fac76e8e4 rbx=000002870361237c rcx=000000000000001c
rdx=ffffb80fac76ea00 rsi=00007ff608030000 rdi=0000000000000000
rip=00007ff60803c3ac rsp=000000c21947fa70 rbp=000000c21947fab9
r8=0000000000000068 r9=ffffb80fac76e908 r10=0000000000000000
r11=ffffb80fac76e800 r12=0000000000000000 r13=0000000000000000
r14=0000000000020375 r15=00007ff608030000
iopl=0 nv up ei pl zr na po nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00040246
notepad!wWinMain+0x2b4:
00007ff6`0803c3ac 0f1f440000 nop dword ptr [rax+rax]
Here's the disassembly:
00007ff6`0803c399 4533c9 xor r9d,r9d
00007ff6`0803c39c 488d4d0f lea rcx,[rbp+0Fh]
00007ff6`0803c3a0 4533c0 xor r8d,r8d
00007ff6`0803c3a3 33d2 xor edx,edx
00007ff6`0803c3a5 48ff15f4c80100 call qword ptr [notepad!_imp_GetMessageW (00007ff6`08058ca0)]
00007ff6`0803c3ac 0f1f440000 nop dword ptr [rax+rax] ; frame pointer here
The 1st argument to GetMessageW is a pointer to a MSG structure so you can see it comes from RBP+0x0f in this case:
1: kd> db 000000c21947fab9 + f
000000c2`1947fac8 10 03 03 00 00 00 00 00-00 04 00 00 00 00 00 00 ................
000000c2`1947fad8 be ba 00 00 00 00 00 00-c0 2f 67 03 87 02 00 00 ........./g.....
000000c2`1947fae8 96 6e 07 00 ab 02 00 00-80 01 00 00 00 00 00 00 .n..............
000000c2`1947faf8 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
000000c2`1947fb08 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
000000c2`1947fb18 b6 59 05 08 f6 7f 00 00-01 00 00 00 00 00 00 00 .Y..............
000000c2`1947fb28 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
000000c2`1947fb38 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
In this case the WM_ message is 0x400.
Beside the kernel debugger, it's interesting to see that all calls to nt!KeUserModeCallback are surrounded by calls to nt!EtwTraceBeginCallback and nt!EtwTraceEndCallback (below an example from win32Kfull.sys in the fnHkINLPMSG function)
.text:00000001C009D429 call cs:__imp_EtwTraceBeginCallback
.text:00000001C009D430 nop dword ptr [rax+rax+00h]
.text:00000001C009D435 lea rax, [rsp+158h+arg_10]
.text:00000001C009D43D mov [rsp+158h+BugCheckParameter4], rax
.text:00000001C009D442 lea r9, [rsp+158h+var_110]
.text:00000001C009D447 mov r8d, 58h ; 'X'
.text:00000001C009D44D lea rdx, [rsp+158h+var_E8]
.text:00000001C009D452 lea ecx, [r8-29h]
.text:00000001C009D456 call cs:__imp_KeUserModeCallback
.text:00000001C009D45D nop dword ptr [rax+rax+00h]
.text:00000001C009D462 mov r12d, eax
.text:00000001C009D465 mov ecx, 2Fh ; '/'
.text:00000001C009D46A call cs:__imp_EtwTraceEndCallback
So using ETW is definitely a possibility. Although I haven't tested it, I suspect the output from the event is quite "raw" without any mention of function names, so it probably requires more work after getting the output from ETW.
Related
I'm implementing a PNG encoder in VHDL for learning purposes. It works with image sizes from 1x1 to 4x4. At the image size of 5x5 there is a behaviour I can't understand:
When encoding raw data with values 0...24, the encoding works. However, when using raw data with values 255...231, it generates a broken image.
Input values 0...24:
> hexdump -C png_encoder/gen/test_img_no_compression_5x5.png
00000000 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 |.PNG........IHDR|
00000010 00 00 00 05 00 00 00 05 08 00 00 00 00 a8 04 79 |...............y|
00000020 39 00 00 00 4c 49 44 41 54 78 01 00 04 00 fb ff |9...LIDATx......|
00000030 00 00 01 02 00 04 00 fb ff 03 04 00 05 00 04 00 |................|
00000040 fb ff 06 07 08 09 00 04 00 fb ff 00 0a 0b 0c 00 |................|
00000050 04 00 fb ff 0d 0e 00 0f 00 04 00 fb ff 10 11 12 |................|
00000060 13 00 04 00 fb ff 00 14 15 16 01 02 00 fd ff 17 |................|
00000070 18 0b a4 01 2d d5 1f a2 6d 00 00 00 00 49 45 4e |....-...m....IEN|
00000080 44 ae 42 60 82 |D.B`.|
00000085
> pngcheck -vv png_encoder/gen/test_img_no_compression_5x5.png
File: png_encoder/gen/test_img_no_compression_5x5.png (133 bytes)
chunk IHDR at offset 0x0000c, length 13
5 x 5 image, 8-bit grayscale, non-interlaced
chunk IDAT at offset 0x00025, length 76
zlib: deflated, 32K window, superfast compression
row filters (0 none, 1 sub, 2 up, 3 avg, 4 paeth):
0 0 0 0 0 (5 out of 5)
chunk IEND at offset 0x0007d, length 0
No errors detected in png_encoder/gen/test_img_no_compression_5x5.png (3 chunks, -432.0% compression).
Input values 255...231:
> hexdump -C png_encoder/gen/test_img_no_compression_5x5.png
00000000 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 |.PNG........IHDR|
00000010 00 00 00 05 00 00 00 05 08 00 00 00 00 a8 04 79 |...............y|
00000020 39 00 00 00 4c 49 44 41 54 78 01 00 04 00 fb ff |9...LIDATx......|
00000030 00 ff fe fd 00 04 00 fb ff fc fb 00 fa 00 04 00 |................|
00000040 fb ff f9 f8 f7 f6 00 04 00 fb ff 00 f5 f4 f3 00 |................|
00000050 04 00 fb ff f2 f1 00 f0 00 04 00 fb ff ef ee ed |................|
00000060 ec 00 04 00 fb ff 00 eb ea e9 01 02 00 fd ff e8 |................|
00000070 e7 6a 21 17 bc 9a 17 87 e7 00 00 00 00 49 45 4e |.j!..........IEN|
00000080 44 ae 42 60 82 |D.B`.|
00000085
> pngcheck -vv png_encoder/gen/test_img_no_compression_5x5.png
File: png_encoder/gen/test_img_no_compression_5x5.png (133 bytes)
chunk IHDR at offset 0x0000c, length 13
5 x 5 image, 8-bit grayscale, non-interlaced
chunk IDAT at offset 0x00025, length 76
zlib: deflated, 32K window, superfast compression
row filters (0 none, 1 sub, 2 up, 3 avg, 4 paeth):
zlib: inflate error = -3 (data error)
(0 out of 5)
ERRORS DETECTED in png_encoder/gen/test_img_no_compression_5x5.png
How to interpret the error message zlib: inflate error = -3 (data error)?
I read https://www.zlib.net/zlib_how.html, but didn't find more specific information. My first guess was the row filters are incorrect, but since both files are structured the same, this is unlikely. Is there something wrong with the ADLER32 calculation in the second case (possibly some overflow)?
It was an overflow in the ADLER32 checksum calculation. Specifically, there were two 16 bit numbers added and truncated before applying the modulo with 65521. Unfortunately my ADLER32 unittest didn't catch it, yet.
However, the error message was shown several times during the implementation and I was always not sure about the cause. If anybody could elaborate the error message or explain how to get a better error message, I would be glad to hear it.
See NFC reader "SELECT (by AID)" APDU is not routed to Android device on debugging and eventual results. TL;DR the reader might simply be defunct.
I have ACR122U nfc reader. I try to run this example http://www.nfc-tools.org/index.php?title=Libnfc:APDU_example#apdu_example.c on my Ubuntu machine.
This is the log output I get when I tap my Android device (should be in HCE mode) to the reader:
./apdu_example
debug libnfc.general log_level is set to 3
debug libnfc.general allow_autoscan is set to true
debug libnfc.general allow_intrusive_scan is set to false
debug libnfc.general 0 device(s) defined by user
./apdu_example uses libnfc libnfc-1.7.1
debug libnfc.driver.acr122_usb device found: Bus 001 Device 088 Name ACS ACR122
debug libnfc.general 1 device(s) found using acr122_usb driver
debug libnfc.driver.acr122_usb 3 element(s) have been decoded from "acr122_usb:001:088"
debug libnfc.driver.acr122_usb TX: 62 00 00 00 00 00 00 01 00 00
debug libnfc.driver.acr122_usb RX: 80 02 00 00 00 00 00 00 81 00 3b 00
debug libnfc.driver.acr122_usb ACR122 PICC Operating Parameters
debug libnfc.driver.acr122_usb TX: 6f 05 00 00 00 00 00 00 00 00 ff 00 51 00 00
debug libnfc.driver.acr122_usb RX: 80 01 00 00 00 00 00 02 fe 00 00
debug libnfc.chip.pn53x GetFirmwareVersion
debug libnfc.driver.acr122_usb TX: 6f 07 00 00 00 00 00 00 00 00 ff 00 00 00 02 d4 02
debug libnfc.driver.acr122_usb RX: 80 08 00 00 00 00 00 02 fe 00 d5 03 32 01 06 07 90 00
debug libnfc.chip.pn53x SetParameters
debug libnfc.driver.acr122_usb TX: 6f 08 00 00 00 00 00 00 00 00 ff 00 00 00 03 d4 12 14
debug libnfc.driver.acr122_usb RX: 80 04 00 00 00 00 00 02 fe 00 d5 13 90 00
debug libnfc.general "ACS / ACR122U PICC Interface" (acr122_usb:001:088) has been claimed.
debug libnfc.chip.pn53x ReadRegister
debug libnfc.driver.acr122_usb TX: 6f 11 00 00 00 00 00 00 00 00 ff 00 00 00 0c d4 06 63 02 63 03 63 0d 63 38 63 3d
debug libnfc.driver.acr122_usb RX: 80 09 00 00 00 00 00 02 fe 00 d5 07 00 00 00 00 00 90 00
debug libnfc.chip.pn53x PN53X_REG_CIU_TxMode (Defines the transmission data rate and framing during transmission)
debug libnfc.chip.pn53x PN53X_REG_CIU_RxMode (Defines the transmission data rate and framing during receiving)
debug libnfc.chip.pn53x WriteRegister
debug libnfc.driver.acr122_usb TX: 6f 0d 00 00 00 00 00 00 00 00 ff 00 00 00 08 d4 08 63 02 80 63 03 80
debug libnfc.driver.acr122_usb RX: 80 04 00 00 00 00 00 02 fe 00 d5 09 90 00
debug libnfc.chip.pn53x RFConfiguration
debug libnfc.driver.acr122_usb TX: 6f 09 00 00 00 00 00 00 00 00 ff 00 00 00 04 d4 32 01 00
debug libnfc.driver.acr122_usb RX: 80 04 00 00 00 00 00 02 fe 00 d5 33 90 00
debug libnfc.chip.pn53x RFConfiguration
debug libnfc.driver.acr122_usb TX: 6f 09 00 00 00 00 00 00 00 00 ff 00 00 00 04 d4 32 01 01
debug libnfc.driver.acr122_usb RX: 80 04 00 00 00 00 00 02 fe 00 d5 33 90 00
debug libnfc.chip.pn53x RFConfiguration
debug libnfc.driver.acr122_usb TX: 6f 0b 00 00 00 00 00 00 00 00 ff 00 00 00 06 d4 32 05 ff ff ff
debug libnfc.driver.acr122_usb RX: 80 04 00 00 00 00 00 02 fe 00 d5 33 90 00
NFC reader: ACS / ACR122U PICC Interface opened
Polling for target...
debug libnfc.chip.pn53x ReadRegister
debug libnfc.driver.acr122_usb TX: 6f 13 00 00 00 00 00 00 00 00 ff 00 00 00 0e d4 06 63 02 63 03 63 05 63 38 63 3c 63 3d
debug libnfc.driver.acr122_usb RX: 80 0a 00 00 00 00 00 02 fe 00 d5 07 80 80 43 00 10 00 90 00
debug libnfc.chip.pn53x InListPassiveTarget
debug libnfc.chip.pn53x No timeout
debug libnfc.driver.acr122_usb TX: 6f 09 00 00 00 00 00 00 00 00 ff 00 00 00 04 d4 4a 01 00
debug libnfc.driver.acr122_usb RX: 80 0e 00 00 00 00 00 02 fe 00 d5 4b 01 01 08 03 20 04 01 02 03 04 90 00
Target detected!
=> a4 04 00 07 f0 01 02 03 04 05 06 00
debug libnfc.chip.pn53x InDataExchange
debug libnfc.chip.pn53x Timeout value: 5000
debug libnfc.driver.acr122_usb TX: 6f 14 00 00 00 00 00 00 00 00 ff 00 00 00 0f d4 40 01 a4 04 00 07 f0 01 02 03 04 05 06 00
res from transceive: -6
debug libnfc.chip.pn53x InDataExchange
debug libnfc.chip.pn53x Timeout value: 5000
debug libnfc.driver.acr122_usb TX: 6f 14 00 00 00 00 00 00 00 00 ff 00 00 00 0f d4 40 01 a4 04 00 07 f0 01 02 03 04 05 06 00
Basically I can see that my Android device is seen by the reader as I can see the UID (01 02 03 04) (or another UID if I tap another device). After that transmitting select AID apdu just timeouts and I can see no relevant response in my Android logs.
On the Android device I have an application installed with the AID I am trying to select - f0 01 02 03 04 05 06.
Can this be a problem with this particular reader? There are other ADPUs which also seem to stop the reader from responding, e.g. FF 00 00 00 02 D4 04 just gives me no response. Can I diagnose the hardware somehow?
I'm trying to do some remote hypervisor kernel debugging in WinDBG (latest version: 10.0.15063.468). The connection is established through the local network, everything works fine, I can break and display the stack or memory, but for some odd reason the search command doesn't work with the simplest stuff:
kd> db 0xfffff80002458350 L20
fffff800`02458350 00 00 00 00 40 00 00 42-2e 72 65 6c 6f 63 00 00 ....#..B.reloc..
fffff800`02458360 0c 06 00 00 00 00 40 01-00 08 00 00 00 a0 10 00 ......#.........
kd> s -sa 0xfffff80002458350 L20
fffff800`02458357 "B.reloc"
kd> s -b 0xfffff80002458350 L20 0x6c
kd> s -b 0xfffff80002458350 L20 0x72
kd> s -b 0xfffff80002458350 L100 0x72
kd> s -a 0xfffff80002458350 L100 "reloc"
kd> db 0xfffff80002458350 L20
fffff800`02458350 00 00 00 00 40 00 00 42-2e 72 65 6c 6f 63 00 00 ....#..B.reloc..
fffff800`02458360 0c 06 00 00 00 00 40 01-00 08 00 00 00 a0 10 00 ......#.........
kd> s -b 0xfffff80002458350 L100 'r'
kd> s -b 0xfffff80002458350 L100 'B'
Why would "-sa" work and "-b" not - what is this magic? Can anyone explain, or at least point me at how I could find the reason for this bizarre behavior?
I'm trying to compile my code into raw binary and as suggested by other SO posts (like this and this) I tried objdump:
$ gcc -c foo.c
$ objcopy -O binary foo.o foo.bin
Then I tried to make sure if this is valid:
$ objdump -d foo.o
foo.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <main>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 48 83 ec 10 sub $0x10,%rsp
8: 89 7d fc mov %edi,-0x4(%rbp)
b: 48 89 75 f0 mov %rsi,-0x10(%rbp)
f: bf 00 00 00 00 mov $0x0,%edi
14: b8 00 00 00 00 mov $0x0,%eax
19: e8 00 00 00 00 callq 1e <main+0x1e>
1e: b8 00 00 00 00 mov $0x0,%eax
23: c9 leaveq
24: c3 ret
$ hexdump -C foo.bin
00000000 14 00 00 00 00 00 00 00 01 7a 52 00 01 78 10 01 |.........zR..x..|
00000010 1b 0c 07 08 90 01 00 00 1c 00 00 00 1c 00 00 00 |................|
00000020 00 00 00 00 25 00 00 00 00 41 0e 10 86 02 43 0d |....%....A....C.|
00000030 06 60 0c 07 08 00 00 00 |.`......|
00000038
Evidently something is wrong. I checked this with the results of a gcc cross-compilation, with much the same obviously incorrect results.
You can pass -j .text to objcopy.
I have just started studying X86 Assembly Language.
My doubt -
When I am using the DOS DEBUG program to look at memory location, I am getting slightly different values on examining the same memory location using two different segment:offset addresses. I.e.-
Aren't D 40[0]:17 and D 41[0]:7 supposed to give exactly same output? since both of them give same address on adding segment + offset = 400+17 = 410+7 = 417H
The results which I get - (notice they are slightly different)
-D 40:17
0040:0010 00-00 00 1E 00 1E 00 0D 1C .........
0040:0020 44 20 20 39 34 05 34 05-3A 27 39 0A 0D 1C 44 20 D 94.4.:'9...D
0040:0030 20 39 34 05 30 0B 3A 27-31 02 37 08 0D 1C 00 00 94.0.:'1.7.....
0040:0040 93 00 C3 00 00 00 00 00-00 03 50 00 00 10 00 00 ..........P.....
0040:0050 00 18 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0040:0060 0F 0C 00 D4 03 29 30 00-00 00 00 00 91 DA 10 00 .....)0.........
0040:0070 00 00 00 00 00 00 08 00-14 14 14 14 01 01 01 01 ................
0040:0080 1E 00 3E 00 18 10 00 60-F9 11 0B 00 50 01 00 00 ..>....`....P...
0040:0090 00 00 00 00 00 00 10 .......
-D 41:7
0041:0000 00-00 00 2C 00 2C 00 44 20 ...,.,.D
0041:0010 20 39 34 05 31 02 3A 27-37 08 0D 1C 0D 1C 44 20 94.1.:'7.....D
0041:0020 20 39 34 05 30 0B 3A 27-31 02 37 08 0D 1C 00 00 94.0.:'1.7.....
0041:0030 08 00 C3 00 00 00 00 00-00 03 50 00 00 10 00 00 ..........P.....
0041:0040 00 18 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0041:0050 0F 0C 00 D4 03 29 30 00-00 00 00 00 1C DB 10 00 .....)0.........
0041:0060 00 00 00 00 00 00 08 00-14 14 14 14 01 01 01 01 ................
0041:0070 1E 00 3E 00 18 10 00 60-F9 11 0B 00 50 01 00 00 ..>....`....P...
0041:0080 00 00 00 00 00 00 10 .......
You are looking at the BIOS data area, whose contents changes over time since it contains things like the state of shift/control/alt keys, the read/write positions of the keyboard buffer and the timer.