Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

false positive on NtPowerInformation parameter #1 #1247

Closed
derekbruening opened this issue Nov 28, 2014 · 3 comments
Closed

false positive on NtPowerInformation parameter #1 #1247

derekbruening opened this issue Nov 28, 2014 · 3 comments

Comments

@derekbruening
Copy link
Contributor

From bruen...@google.com on May 22, 2013 13:50:20

xref similar issue in issue #1185 c#2

running win8 calc I see:

Error #8: UNINITIALIZED READ: reading 0x02e0db58-0x02e0db6c 20 byte(s) within 0x02e0db50-0x02e0db6c
#0 system call NtPowerInformation parameter #1
#1 KERNEL32.dll!PowerCreateRequest
#2 WinMain
Note: @0:00:19.282 in thread 2808

Error #9: UNINITIALIZED READ: reading 0x00bedcf1-0x00bedcf4 3 byte(s) within 0x00bedce8-0x00bedcf8
#0 system call NtPowerInformation parameter #1
#1 KERNEL32.dll!PowerSetRequest
#2 WinMain
Note: @0:00:19.297 in thread 2808

Error #10: UNINITIALIZED READ: reading 0x00bedcf1-0x00bedcf4 3 byte(s) within 0x00bedce8-0x00bedcf8
#0 system call NtPowerInformation parameter #1
#1 KERNEL32.dll!PowerClearRequest
#2 WinMain

NTSYSAPI
NTSTATUS
NTAPI
ZwPowerInformation(
IN POWER_INFORMATION_LEVEL PowerInformationLevel,
IN PVOID InputBuffer OPTIONAL,
IN ULONG InputBufferLength,
OUT PVOID OutputBuffer OPTIONAL,
IN ULONG OutputBufferLength
);

app xsp=0x004de274
arg 0 = 0x2b
arg 1 = 0x2ccdb50
arg 2 = 0x1c
arg 3 = 0x4de28c
arg 4 = 0x4

system call #93==93.0 NtPowerInformation
#0 KERNEL32.dll!PowerCreateRequest+0x32 (0x7510149c <KERNEL32.dll+0x2149c>) modid:0
#1 fp=0x004de294 parent=0x004dfe58 WinMain +0x1102 (0x0100210c <calc.exe+0x210c>) modid:0
Error #6: UNINITIALIZED READ: reading 0x02ccdb58-0x02ccdb6c 20 byte(s) within 0x02ccdb50-0x02ccdb6c

so some part of InputBuffer is not initialized, for some codes at least

CallNtPowerInformation in DDK http://msdn.microsoft.com/en-us/library/windows/desktop/aa372675(v=vs.85).aspx /extsw/win32/visual_studio/headers-SDK8.0/Include/um/winnt.h:} POWER_INFORMATION_LEVEL;
/extsw/win32/visual_studio/headers-SDK8.0/Include/um/powerbase.h: In POWER_INFORMATION_LEVEL In

0x2b == PowerRequestCreate (matches kernel32 name)

the input buffer may well be REASON_CONTEXT: looking into it

Original issue: http://code.google.com/p/drmemory/issues/detail?id=1247

@derekbruening
Copy link
Contributor Author

From bruen...@google.com on May 22, 2013 12:39:42

that was PowerCreateRequest

we also have:

**** TODO PowerSetRequest and PowerClearRequest

app xsp=0x009fdf2c
arg 0 = 0x2c <== PowerRequestAction
arg 1 = 0x9fdf48
arg 2 = 0x10
arg 3 = 0x0
arg 4 = 0x0
system call #93==93.0 NtPowerInformation

0 KERNEL32.dll!PowerSetRequest+0x59 (0x75101596 <KERNEL32.dll+0x21596>) modid:0

1 fp=0x009fdf58 parent=0x009ffb24 WinMain +0x1119 (0x01002123 <calc.exe+0x2123>) modid:0

Error #6: UNINITIALIZED READ: reading 0x009fdf51-0x009fdf54 3 byte(s) within 0x009fdf48-0x009fdf58

BOOL PowerSetRequest(
In HANDLE PowerRequest,
In POWER_REQUEST_TYPE RequestType
);

0:000> dds esp
00c3de2c 01002123 calc!WinMain+0x10f7
00c3de30 000001d8
00c3de34 00000003 <== PowerRequestAwayModeRequired

it passes a 0x10-byte struct to NtPowerInformation.
1st 2 fields look like args to PowerSetRequest.
then we have a 1-byte field (BOOLEAN?) and the final field here is 0.

KERNEL32!PowerSetRequest+0x39:
75101576 8b4508 mov eax,[ebp+0x8]
75101579 56 push esi
7510157a 56 push esi
7510157b 8945f0 mov [ebp-0x10],eax
7510157e 6a10 push 0x10
75101580 8d45f0 lea eax,[ebp-0x10]
75101583 50 push eax
75101584 6a2c push 0x2c
75101586 894df4 mov [ebp-0xc],ecx
75101589 c645f801 mov byte ptr [ebp-0x8],0x1
7510158d 8975fc mov [ebp-0x4],esi
75101590 ff15900d1675 call dword ptr [KERNEL32!_imp__NtPowerInformation (75160d90)]

PowerClearRequest is similar:
0:000> dds esp
0060de14 01004070 calc!WinMain+0x305c
0060de18 000001d0
0060de1c 00000003
KERNEL32!PowerClearRequest+0x37:
75101501 8bcb mov ecx,ebx
75101503 8b4508 mov eax,[ebp+0x8]
75101506 53 push ebx
75101507 53 push ebx
75101508 8945f0 mov [ebp-0x10],eax
7510150b 6a10 push 0x10
7510150d 8d45f0 lea eax,[ebp-0x10]
75101510 50 push eax
75101511 6a2c push 0x2c
75101513 894df4 mov [ebp-0xc],ecx
75101516 885df8 mov [ebp-0x8],bl <== just one byte
75101519 895dfc mov [ebp-0x4],ebx
7510151c ff15900d1675 call dword ptr [KERNEL32!_imp__NtPowerInformation (75160d90)]
0:000> dds esp
0060dde8 0000002c
0060ddec 0060de00
0060ddf0 00000010
0060ddf4 00000000
0060ddf8 00000000
0:000> dd ebp-10 L8
0060de00 000001d0 00000003 77902200 00000000

x64:
KERNEL32!PowerSetRequest+0x1c:
000007fa0aa2e798 8d4303 lea eax,[rbx+3] 000007fa0aa2e79b 4533c9 xor r9d,r9d
000007fa0aa2e79e 48894c2430 mov qword ptr [rsp+30h],rcx 000007fa0aa2e7a3 488d542430 lea rdx,[rsp+30h]
000007fa0aa2e7a8 458d4118 lea r8d,[ r9 +18h] 000007fa0aa2e7ac 418d492c lea ecx,[ r9 +2Ch]
000007fa0aa2e7b0 89442438 mov dword ptr [rsp+38h],eax 000007fa0aa2e7b4 c644243c01 mov byte ptr [rsp+3Ch],1 <=== just one byte
000007fa0aa2e7b9 48895c2440 mov qword ptr [rsp+40h],rbx \<=== pointer-sized 000007fa0aa2e7be 895c2420 mov dword ptr [rsp+20h],ebx
000007fa0aa2e7c2 ff1570ed0d00 call qword ptr [KERNEL32!_imp_NtPowerInformation (000007fa0ab0d538)]

@derekbruening
Copy link
Contributor Author

From bruen...@google.com on May 22, 2013 14:10:12

**** TODO actually PowerRequestCreate does not take a REASON_CONTEXT!

passed to PowerCreateRequest:
0:000> dt -b REASON_CONTEXT 0187f884
+0x000 Version : 0
+0x004 Flags : 1
+0x008 Reason :
+0x000 Detailed :
+0x000 LocalizedReasonModule : 0x003a72a8
+0x004 LocalizedReasonId : 0x3a9b170
+0x008 ReasonStringCount : 0x187f8b4
+0x00c ReasonStrings : 0x002f5bc7
+0x000 SimpleReasonString : 0x003a72a8 "Power outage"

passed to NtPowerInformation:
0:000> dt -b real_cxt
Local var @ 0x17fbed68 Type _REASON_CONTEXT*
0x03a9b2d8
+0x000 Version : 0
+0x004 Flags : 1
+0x008 Reason :
+0x000 Detailed :
+0x000 LocalizedReasonModule : 0x001a0018
+0x004 LocalizedReasonId : 0x3a72a8
+0x008 ReasonStringCount : 0
+0x00c ReasonStrings : (null)
+0x000 SimpleReasonString : 0x001a0018
0:000> dd 0x001a0018
001a0018 ???????? ???????? ???????? ????????
0:000> dt -b UNICODE_STRING 0x03a9b2d8 +8
"Power outage"
+0x000 Length : 0x18
+0x002 MaximumLength : 0x1a
+0x004 Buffer : 0x003a72a8 "Power outage"

but what about if it's POWER_REQUEST_CONTEXT_VERSION?

I tried:
cxt.Version = POWER_REQUEST_CONTEXT_VERSION;
cxt.Flags = POWER_REQUEST_CONTEXT_DETAILED_STRING;
LPWSTR array[] = {L"Reason1", L"Reason2"};
cxt.Reason.Detailed.LocalizedReasonModule = NULL;
cxt.Reason.Detailed.LocalizedReasonId = 0;
cxt.Reason.Detailed.ReasonStringCount = sizeof(array)/sizeof(array[0]);
cxt.Reason.Detailed.ReasonStrings = array;
h = PowerCreateRequest(&cxt);
=>
0:000> dd @@(real_cxt)
040cb318 00000000 00000002 007c007a 040cb334
040cb328 00000000 00000002 040cb3b0 003a0043
0:000> du 040cb334
040cb334 "C:\derek\drmemory\git\build_x86_"
040cb374 "dbg\tests\app_suite_tests.exe"

size is still 0x1c.

cxt.Reason.Detailed.LocalizedReasonModule = GetModuleHandle("ntdll.dll");

=>
0:000> dd @@(real_cxt)
0354b350 00000000 00000002 003c003a 0354b36c
0354b360 00000000 00000002 0354b3a8 003a0043
0:000> du 0354b36c
0354b36c "C:\Windows\SYSTEM32\ntdll.dll"

I don't see the array of strings passed to the kernel at all:

0:000> dds @@(pt->mc.xsp)
00bff508 7510149c KERNEL32!PowerCreateRequest+0x32
00bff50c 0000002b
00bff510 0354b350
00bff514 0000001c
00bff518 00bff520
00bff51c 00000004
00bff520 ffffffff
00bff524 0354b350
00bff528 00bff5e4
00bff52c 0102cc1a
app_suite_tests!PowerTest_PowerCreateRequest_Test::TestBody+0x24a [c:\derek\drmemory\git\src\tests\app_suite\power_tests_win.cpp @ 48]
00bff530 00bff5bc
00bff534 67b25d6e
00bff538 00000000
00bff53c 00000000
00bff540 00000000
00bff544 0354b100
00bff548 01117314 app_suite_tests!testing::internal::TestFactoryImpl<NtGdiTests_DeviceContext_Test>::vftable'+0xec8 00bff54c 01117324 app_suite_tests!testing::internal::TestFactoryImpl<NtGdiTests_DeviceContext_Test>::vftable'+0xed8
00bff550 00000000
00bff554 0354b270
00bff558 0354b170
00bff55c 0354b270
00bff560 00bff501
00bff564 00000000
00bff568 00000000
00bff56c 00000001
00bff570 00000000
00bff574 0354b170
00bff578 00bff598
00bff57c 01065bc7 app_suite_tests!testing::internal::GTestFlagSaver::GTestFlagSaver+0x157 [c:\derek\drmemory\git\src\third_party\googletest\src\gtest-internal-inl.h @ 170]
00bff580 01151bd4 app_suite_tests!testing::FLAGS_gtest_stream_result_to
00bff584 67b25d12
0:000> dt -b REASON_CONTEXT 00bff5bc
+0x000 Version : 0
+0x004 Flags : 2
+0x008 Reason :
+0x000 Detailed :
+0x000 LocalizedReasonModule : 0x778b0000
+0x004 LocalizedReasonId : 0
+0x008 ReasonStringCount : 2
+0x00c ReasonStrings : 0x00bff548
+0x000 SimpleReasonString : 0x778b0000 "婍???"
0:000> dd 0x00bff548
00bff548 01117314 01117324 00000000 0354b270
00bff558 0354b170 0354b270 00bff501 00000000
0:000> du 01117314
01117314 "Reason1"
0:000> du 01117324
01117324 "Reason2"

=>
/* Used by NtPowerInformation.PowerRequestCreate, which is used by

  • kernel32!PowerCreateRequest
    _/
    typedef struct POWER_REQUEST_CREATE {
    /
    First two fields match those in REASON_CONTEXT /
    ULONG Version;
    DWORD Flags;
    /
    XXX: it seems that REASON_CONTEXT.Reason.Detailed.* is all just
    • ignored and only the name of the module is passed to the kernel
    • (name of exe, if NULL). Why have the array then? Where is the
    • resource ID passed?
      */
      UNICODE_STRING ReasonString;
      } POWER_REQUEST_CREATE;

@derekbruening
Copy link
Contributor Author

From derek.br...@gmail.com on May 22, 2013 21:03:23

This issue was closed by revision r1392 .

Status: Fixed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant