读取所有文件以缓冲或将其映射为部分。比执行下一个代码:
extern "C" PCSTR __fastcall findRN(SIZE_T cb, PCSTR sz);
void processLine(SIZE_T len, PCSTR line)
{
DbgPrint("%.*s\n", len, line);
}
NTSTATUS process(PCSTR buf, SIZE_T cb)
{
PCSTR end = buf + cb, line = buf;
while (buf = findRN(end - line, line))
{
processLine(buf - line, line);
line = buf + 2;
}
if (line != end)
{
processLine(end - line, line);
}
return 0;
}
findRN
在c/c++上的实现
PCSTR __fastcall findRN(SIZE_T cb, PCSTR sz)
{
if (cb < 2)
{
return 0;
}
cb--;
do
{
if (*sz++ == '\r')
{
if (*sz == '\n')
{
return sz - 1;
}
}
} while (--cb);
return 0;
}
如果您需要/想要超快速最有效的实现,请在 asm.xml 中执行此操作。例如 x64:
findRN proc
cmp rcx,1
ja @@0
xor rax,rax
ret
@@0:
mov ax,0a0dh
xchg rdi,rdx
dec rcx
@@1:
repne scasb
jne @@2
cmp [rdi],ah
jne @@1
@@2:
sete al
dec rdi
movzx rax,al
neg rax
and rax,rdi
xchg rdi,rdx
ret
findRN endp
在 x86 代码上相同,只需将寄存器名称中的r更改为e
地图文件:
NTSTATUS process(POBJECT_ATTRIBUTES poa)
{
HANDLE hFile, hSection = 0;
IO_STATUS_BLOCK iosb;
NTSTATUS status = NtOpenFile(&hFile, FILE_GENERIC_READ, poa, &iosb,
FILE_SHARE_VALID_FLAGS, FILE_SYNCHRONOUS_IO_NONALERT);
if (0 <= status)
{
FILE_STANDARD_INFORMATION fsi;
if (0 <= (status = NtQueryInformationFile(hFile, &iosb, &fsi, sizeof(fsi), FileStandardInformation)))
{
if (fsi.EndOfFile.HighPart)
{
status = STATUS_FILE_TOO_LARGE;
}
else if (!fsi.EndOfFile.LowPart)
{
status = STATUS_MAPPED_FILE_SIZE_ZERO;
}
else
{
status = NtCreateSection(&hSection, SECTION_MAP_READ, 0, 0, PAGE_READONLY, SEC_COMMIT, hFile);
}
}
NtClose(hFile);
if (0 <= status)
{
PVOID BaseAddress = 0;
SIZE_T ViewSize = 0;
status = ZwMapViewOfSection(hSection, NtCurrentProcess(), &BaseAddress, 0,
0, 0, &ViewSize, ViewUnmap, 0, PAGE_READONLY);
NtClose(hSection);
if (0 <= status)
{
status = process((PCSTR)BaseAddress, fsi.EndOfFile.LowPart);
ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
}
}
}
return status;
}