delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2016/06/30/17:27:57

X-Recipient: archive-cygwin AT delorie DOT com
DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id
:list-unsubscribe:list-subscribe:list-archive:list-post
:list-help:sender:subject:to:references:from:message-id:date
:mime-version:in-reply-to:content-type; q=dns; s=default; b=T96X
CUVvru7mqWsFXTcKecvBo4YkQAAkeSI54pptLFRR53IRSYp65niR2h1XxS3qsE8D
r1Ap2oawMJ024LUuYHjbBrTqUrcePkyAe6ykLgk/uAFG8d9VJjgByik2uHhaQWnw
03zopaSisTrWMFtu98No9EjYIaTdcOfORLuYUco=
DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id
:list-unsubscribe:list-subscribe:list-archive:list-post
:list-help:sender:subject:to:references:from:message-id:date
:mime-version:in-reply-to:content-type; s=default; bh=hxtDKES88O
2OvqSobwPCsW311ZQ=; b=mGI+21EKqT+2k+EdydVoFL1dRi67kuddAWLqak5rXb
xrmUeGurH0Od9j5nKf4uMC51PWR1hv39IMEv09ehYsCwI8inCY41kQr97nQ4XHKS
WcMxU1yjZTYQz5dSirQ9KaBRx0eHEGNgWlXsGyZThyWSwKh1/aZFz40k8gu3yOVq
U=
Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Id: <cygwin.cygwin.com>
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sourceware.org/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sourceware.org/ml/#faqs>
Sender: cygwin-owner AT cygwin DOT com
Mail-Followup-To: cygwin AT cygwin DOT com
Delivered-To: mailing list cygwin AT cygwin DOT com
Authentication-Results: sourceware.org; auth=none
X-Virus-Found: No
X-Spam-SWARE-Status: No, score=-2.4 required=5.0 tests=BAYES_00,FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 spammy=lying, 864, 3579, kills
X-HELO: mail-wm0-f48.google.com
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:to:references:from:message-id:date :user-agent:mime-version:in-reply-to; bh=o5jfv322wQzbnN8ZiUGSizbNd78IPNGQfRAffWp9cpE=; b=fB5rsquQVGIXjnb1BvapDczRkeLXG5sUo9KxdMH6VeZk8UCF3e63XQF2ptCN9MOu5m VyucTdNHxsaRrYczAVgvQiP+WJxk3RazJzxIjDLrwUdASnGQE/9rDhDoKuWESrw1Bhyx lcd3sX6WELwOdhEBolvd0GKqxE++dvNfnCL8ymf7794bWVCT0pwkBwuuh3ifxIQn5YYn SWGT7UFYVgAgnePf+5oBzfoF6ub0JrdSPjTEG8U3uISsllt6Z4P8ej28WUPdKp/93iNu NE15SMptSMPVuIsL+lW9J3gj9kpSX+Zr4qop6KQ7K5voiV2jMkfkyLRAPDqeUlD9XEH7 GPKQ==
X-Gm-Message-State: ALyK8tIoCIptfNZ8Xf/BZzQ7Q6MGkhM7kl15YW4U1uOrMbTKMCT+BCX3Pu1dqbQOcVb6pg==
X-Received: by 10.28.26.67 with SMTP id a64mr28093867wma.70.1467322046786; Thu, 30 Jun 2016 14:27:26 -0700 (PDT)
Subject: Re: Why does ldd not show cyg*.dll in its output?
To: cygwin AT cygwin DOT com
References: <3AD694B4-17D4-4963-88FD-435AD4DD36D5 AT etr-usa DOT com> <4b37d689-285d-7dd4-3e3d-d40b4ee2f81f AT cygwin DOT com> <cb61e083-4229-6662-4815-130c41dfe2a4 AT t-online DOT de> <8AFB6FBD-0E6A-4DE7-BB08-61D12D20ED40 AT etr-usa DOT com> <1b8d57d1-b8f8-6027-ef4a-073a60fbae84 AT gmail DOT com>
From: David Macek <david DOT macek DOT 0 AT gmail DOT com>
Message-ID: <a62bb487-1a0c-77a0-ce29-09520dcbdb7b@gmail.com>
Date: Thu, 30 Jun 2016 23:27:23 +0200
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.1.1
MIME-Version: 1.0
In-Reply-To: <1b8d57d1-b8f8-6027-ef4a-073a60fbae84@gmail.com>
X-IsSubscribed: yes

--------------ms010202040100050508010908
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable

On 29. 6. 2016 23:45, David Macek wrote:
> I can try watching them side by side in debuggers tomorrow, maybe I'll fi=
nd something.

Yep, found something. TL;DR the issue is that Windows spins a thread in the=
 process before our DLLs are loaded. Detailed analysis below.

On my Win8.x, the ldd "debugger" receives these events:

 1. CREATE_PROCESS_DEBUG_EVENT
 2. LOAD_DLL_DEBUG_EVENT for ntdll.dll
 3. LOAD_DLL_DEBUG_EVENT for KERNEL32.DLL
 4. LOAD_DLL_DEBUG_EVENT for KERNELBASE.dll
 5. LOAD_DLL_DEBUG_EVENT for msys-intl-8.dll
 6. LOAD_DLL_DEBUG_EVENT for msys-2.0.dll
 7. LOAD_DLL_DEBUG_EVENT for msys-iconv-2.dll
 8. EXCEPTION_DEBUG_EVENT ev.u.Exception =3D {ExceptionRecord =3D {Exceptio=
nCode =3D 2147483651, ExceptionFlags =3D 0, ExceptionRecord =3D 0x0, Except=
ionAddress =3D 0x7ffda38d1b90 <ntdll!LdrInitShimEngineDynamic+816>, NumberP=
arameters =3D 1, ExceptionInformation =3D {0 <repeats 15 times>}}, dwFirstC=
hance =3D 1}
 9. OUTPUT_DEBUG_STRING_EVENT ev.u.DebugString =3D {lpDebugStringData =3D 0=
x23f2a0 <error: Cannot access memory at address 0x23f2a0>, fUnicode =3D 0, =
nDebugStringLength =3D 24}
10. CREATE_THREAD_DEBUG_EVENT ev.u.CreateThread =3D {hThread =3D 0x88, lpTh=
readLocalBase =3D 0x7ff5ffffb000, lpStartAddress =3D 0x180044cf0 <cygthread=
::stub(void*)>}=20
11. EXIT_THREAD_DEBUG_EVENT
12. EXIT_PROCESS_DEBUG_EVENT

I would say events #8 and #9 are not important (ldd ignores them as well). =
Event #10 causes ldd to call `TerminateProcess` because we don't want any o=
f the analyzed program's code to run. This in turn causes events #11 and #1=
2, after which ldd exits.

On my Win10, events are like this:

 1. CREATE_PROCESS_DEBUG_EVENT
 2. LOAD_DLL_DEBUG_EVENT for ntdll.dll
 3. LOAD_DLL_DEBUG_EVENT for KERNEL32.DLL
 4. LOAD_DLL_DEBUG_EVENT for KERNELBASE.dll
(5) LOAD_DLL_DEBUG_EVENT for msys-intl-8.dll
 6. CREATE_THREAD_DEBUG_EVENT ev.u.CreateThread =3D {hThread =3D 0x168, lpT=
hreadLocalBase =3D 0x22c000, lpStartAddress =3D 0x7fff19e80720 <ntdll!RtlFi=
ndActivationContextSectionString+3456>}
 7. EXIT_THREAD_DEBUG_EVENT
 8. EXIT_PROCESS_DEBUG_EVENT

Event #6 is the culprit here. NT apparently starts a thread in our process =
which confuses ldd into believing that the process has finished loading DLL=
 from its import table and kills it, as explained above. The thread appears=
 non-deterministically, too, sometimes I see event #5 (and the associated D=
LL in ldd's output), sometimes not. The thread's entry point is always the =
same and ProcExp reports the same location (I checked in case of some symbo=
l mash-up, as it often happens when debugging across the Cygwin-Windows bou=
ndary). When I broke ldd at `case CREATE_THREAD_DEBUG_EVENT`, the new threa=
d's stack trace (from ProcExp) looked like this:

ntoskrnl.exe!KeSynchronizeExecution+0x3f26
ntoskrnl.exe!KeWaitForMultipleObjects+0x10b5
ntoskrnl.exe!KeWaitForMultipleObjects+0xb6f
ntoskrnl.exe!KeWaitForSingleObject+0x370
ntoskrnl.exe!CmUnRegisterCallback+0x1b02c
ntoskrnl.exe!CmUnRegisterCallback+0x1c225
ntoskrnl.exe!NtVdmControl+0x45822
ntoskrnl.exe!FsRtlFreeExtraCreateParameter+0x44b
ntoskrnl.exe!KeSynchronizeExecution+0x4716
ntoskrnl.exe!KeSynchronizeExecution+0x4690
!RtlUserThreadStart

I came up with this naive fix:

--- ldd.cc.orig 2016-04-28 21:54:57.556500700 +0200
+++ ldd.cc      2016-06-30 22:18:05.332452300 +0200
@@ -357,6 +357,9 @@
            }
          break;
        case CREATE_THREAD_DEBUG_EVENT:
+          if (ev.u.CreateThread.lpStartAddress =3D=3D (void*)0x7fff19e8072=
0) {
+            break;
+          }
          TerminateProcess (hProcess, 0);
          break;
        case EXIT_PROCESS_DEBUG_EVENT:

After which the output switched back to normal. One observed sequence of ev=
ents:

 1. CREATE_PROCESS_DEBUG_EVENT
 2. LOAD_DLL_DEBUG_EVENT for ntdll.dll
 3. LOAD_DLL_DEBUG_EVENT for KERNEL32.DLL
 4. LOAD_DLL_DEBUG_EVENT for KERNELBASE.dll
 5. CREATE_THREAD_DEBUG_EVENT ev.u.CreateThread =3D {hThread =3D 0x14c, lpT=
hreadLocalBase =3D 0x26a000, lpStartAddress =3D 0x7fff19e80720 <ntdll!RtlFi=
ndActivationContextSectionString+3456>}
 6. LOAD_DLL_DEBUG_EVENT for msys-intl-8.dll
 7. CREATE_THREAD_DEBUG_EVENT ev.u.CreateThread =3D {hThread =3D 0x138, lpT=
hreadLocalBase =3D 0x26c000, lpStartAddress =3D 0x7fff19e80720 <ntdll!RtlFi=
ndActivationContextSectionString+3456>}
 8. LOAD_DLL_DEBUG_EVENT for msys-2.0.dll
 9. LOAD_DLL_DEBUG_EVENT for msys-iconv-2.dll
10. CREATE_THREAD_DEBUG_EVENT ev.u.CreateThread =3D {hThread =3D 0x18c, lpT=
hreadLocalBase =3D 0x274000, lpStartAddress =3D 0x7fff19e80720 <ntdll!RtlFi=
ndActivationContextSectionString+3456>}
11. EXCEPTION_DEBUG_EVENT ev.u.Exception =3D {ExceptionRecord =3D {Exceptio=
nCode =3D 2147483651, ExceptionFlags =3D 0, ExceptionRecord =3D 0x0, Except=
ionAddress =3D 0x7fff19f2fd00 <ntdll!LdrInitShimEngineDynamic+864>, NumberP=
arameters =3D 1, ExceptionInformation =3D {0 <repeats 15 times>}}, dwFirstC=
hance =3D 1}
12. OUTPUT_DEBUG_STRING_EVENT ev.u.DebugString =3D {lpDebugStringData =3D 0=
x5ff1a0 <error: Cannot access memory at address 0x5ff1a0>, fUnicode =3D 0, =
nDebugStringLength =3D 24}
13. CREATE_THREAD_DEBUG_EVENT ev.u.CreateThread =3D {hThread =3D 0x118, lpT=
hreadLocalBase =3D 0x276000, lpStartAddress =3D 0x180044cf0 <cygthread::stu=
b(void*)>}
14. EXIT_THREAD_DEBUG_EVENT
15. EXIT_THREAD_DEBUG_EVENT
16. EXIT_THREAD_DEBUG_EVENT
17. EXIT_THREAD_DEBUG_EVENT
18. EXIT_PROCESS_DEBUG_EVENT

Here are some more stacktraces from various points in life of the cuckoo th=
reads, in case they are significant:

ntoskrnl.exe!KeSynchronizeExecution+0x3f26
ntoskrnl.exe!KeWaitForMultipleObjects+0x10b5
ntoskrnl.exe!KeWaitForMultipleObjects+0xb6f
ntoskrnl.exe!KeWaitForSingleObject+0x370
ntoskrnl.exe!KeTestAlertThread+0x591
ntoskrnl.exe!KeReleaseSemaphore+0x4d1
ntoskrnl.exe!KiCheckForKernelApcDelivery+0x23
ntoskrnl.exe!NtDeviceIoControlFile+0x163f
ntoskrnl.exe!NtClose+0x1c37
ntoskrnl.exe!NtClose+0xcb
ntoskrnl.exe!setjmpex+0x3a63
!NtClose+0x14
!RtlGetActiveActivationContext+0x51c
!RtlGetFullPathName_UstrEx+0x4ab
!RtlReleaseRelativeName+0x269
!RtlReleaseRelativeName+0x1f3
!RtlFindActivationContextSectionString+0x3039
!RtlFindActivationContextSectionString+0x11f4
!BaseThreadInitThunk+0x14
!RtlUserThreadStart+0x21

ntoskrnl.exe!KeSynchronizeExecution+0x3f26
ntoskrnl.exe!KeSetEvent+0x6a6
ntoskrnl.exe!MmUnlockPagableImageSection+0xdd
ntoskrnl.exe!KeSynchronizeExecution+0x4b52
!RtlLookupFunctionEntry+0x113f
!RtlReleaseRelativeName+0x248
!RtlReleaseRelativeName+0x1f3
!RtlFindActivationContextSectionString+0x3039
!RtlFindActivationContextSectionString+0x11f4
!BaseThreadInitThunk+0x14
!RtlUserThreadStart+0x21

After some experimentation, I came up with a patch that tries to determine =
whether to ignore a thread based on the thread's entry point lying inside o=
r outside of the memory occupied by ntdll.dll:

--- ldd.cc.orig 2016-04-28 21:54:57.556500700 +0200
+++ ldd.cc      2016-06-30 23:24:20.394384800 +0200
@@ -327,6 +327,10 @@
     {
       bool exitnow =3D false;
       DWORD cont =3D DBG_CONTINUE;
+      MODULEINFO mi;
+      HMODULE ntdll =3D LoadLibrary("ntdll.dll");
+      HMODULE ntdllend =3D NULL;
+      void *entryPoint;
       if (!WaitForDebugEvent (&ev, INFINITE))
        break;
       switch (ev.dwDebugEventCode)
@@ -357,6 +361,31 @@
            }
          break;
        case CREATE_THREAD_DEBUG_EVENT:
+          if (ntdll !=3D NULL)
+            {
+              if (ntdllend =3D=3D NULL)
+                {
+                  /* Using our ntdll.dll HMODULE with a foreign process
+                     should be fine because ntdll.dll is mapped to the same
+                     address in every concurrently executing process and
+                     HMODULEs are just pointers to the image in the process
+                     memory. Using GetModuleHandle(NULL) didn't work for t=
he
+                     author of this code (-> ERROR_INVALID_HANDLE). */
+                  if (GetModuleInformation(hProcess, ntdll, &mi, sizeof(mi=
)))
+                    ntdllend =3D ntdll + (ptrdiff_t)mi.SizeOfImage;
+                  else
+                    ntdll =3D NULL;
+                }
+              if (ntdllend !=3D NULL)
+                {
+                  entryPoint =3D (void*)ev.u.CreateThread.lpStartAddress;
+                  /* If the thread's entry point is in ntdll.dll, let's
+                    assume that this isn't the program's main thread and
+                    ignore it. */
+                  if (ntdll <=3D entryPoint && entryPoint < ntdllend)
+                    break;
+                }
+            }
          TerminateProcess (hProcess, 0);
          break;
        case EXIT_PROCESS_DEBUG_EVENT:
---end---

I can send the patch through proper channels if it passes a sanity check fr=
om someone.

HTH. Cheers.

--=20
David Macek


--------------ms010202040100050508010908
Content-Type: application/pkcs7-signature; name="smime.p7s"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="smime.p7s"
Content-Description: S/MIME Cryptographic Signature

MIAGCSqGSIb3DQEHAqCAMIACAQExDzANBglghkgBZQMEAgEFADCABgkqhkiG
9w0BBwEAAKCCCuwwggUCMIID6qADAgECAhAwzJDbT70jeYw1Cb83uS/9MA0G
CSqGSIb3DQEBCwUAMHUxCzAJBgNVBAYTAklMMRYwFAYDVQQKEw1TdGFydENv
bSBMdGQuMSkwJwYDVQQLEyBTdGFydENvbSBDZXJ0aWZpY2F0aW9uIEF1dGhv
cml0eTEjMCEGA1UEAxMaU3RhcnRDb20gQ2xhc3MgMSBDbGllbnQgQ0EwHhcN
MTUxMjIzMDgyOTQ0WhcNMTYxMjIzMDgyOTQ0WjBKMSAwHgYDVQQDDBdkYXZp
ZC5tYWNlay4wQGdtYWlsLmNvbTEmMCQGCSqGSIb3DQEJARYXZGF2aWQubWFj
ZWsuMEBnbWFpbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
AQCnUGZaXVaGbHTA2s29ZRn4EWF+mN7cEUhAXNs704Brun7YwopS2xsAVuRq
+WGQLWZqVyLRHOnCsx5uqnF5e1ZjEl21l5hrcM2aFEyyTAEVeXvZSk7Oghqj
IPp7u5dWwadD6ck/EkJeqHv4gfyI+/NLutTUaft3pcj9eI4IlGkxK4UO7VMh
TBVi9KyRfLiZJpy1OdQ0JDidQcoLnCqQX7SWcQNko+ujMaw/K3UkT6xFTW0H
Huhq/rBEJPdFG5XHyjsTh72NymPw1JSngKOoETJomaIrSx30CYwmIEXgleKG
RzYmSlSJP8UActCxwz7Qo3BajrH0iu3lHDqbBnviPXoZAgMBAAGjggG3MIIB
szALBgNVHQ8EBAMCBLAwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwME
MAkGA1UdEwQCMAAwHQYDVR0OBBYEFLU/0F3NtsxZQdtsyjsQV+CRUcP1MB8G
A1UdIwQYMBaAFCSBbDlhvkkPj7cbRivJKLUnSG1oMG8GCCsGAQUFBwEBBGMw
YTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3Auc3RhcnRzc2wuY29tMDkGCCsG
AQUFBzAChi1odHRwOi8vYWlhLnN0YXJ0c3NsLmNvbS9jZXJ0cy9zY2EuY2xp
ZW50MS5jcnQwOAYDVR0fBDEwLzAtoCugKYYnaHR0cDovL2NybC5zdGFydHNz
bC5jb20vc2NhLWNsaWVudDEuY3JsMCIGA1UdEQQbMBmBF2RhdmlkLm1hY2Vr
LjBAZ21haWwuY29tMCMGA1UdEgQcMBqGGGh0dHA6Ly93d3cuc3RhcnRzc2wu
Y29tLzBGBgNVHSAEPzA9MDsGCysGAQQBgbU3AQIEMCwwKgYIKwYBBQUHAgEW
Hmh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeTANBgkqhkiG9w0BAQsF
AAOCAQEAkXAWZ3p8s2aNO4q+MAsuph4diGLSiq3adMsWo3/IqAA7nJVkhobz
XXqTd84T0gFgDdbUCEGxL9YQpsM9fJzRZtP46XBdWR/sSA4UMUZsYAVBkRX+
aDSoLn2lAhtoiJlT0HlKiYk3mscEmk4E8/SQkl2Eo7wY0kuV+0nFWt9QI4ip
xSWkYHt9U1puCPL0PLe8voOM0vsBXhjoO3VTTRVIa5n/ssN+8XNxIevtPl5A
w0UQ5ewZrdV7iItgTzdyw8ZYd3dtbSKrg2cBN0n3muDy9sQhF0zqh2YF1Yci
C8vKcMRPceXBV77D6sS16seSoJqQzYKfN0K9pe6zMDnp0seOPjCCBeIwggPK
oAMCAQICEGunin0K14jWUQr5WeTntOEwDQYJKoZIhvcNAQELBQAwfTELMAkG
A1UEBhMCSUwxFjAUBgNVBAoTDVN0YXJ0Q29tIEx0ZC4xKzApBgNVBAsTIlNl
Y3VyZSBEaWdpdGFsIENlcnRpZmljYXRlIFNpZ25pbmcxKTAnBgNVBAMTIFN0
YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTE1MTIxNjAxMDAw
NVoXDTMwMTIxNjAxMDAwNVowdTELMAkGA1UEBhMCSUwxFjAUBgNVBAoTDVN0
YXJ0Q29tIEx0ZC4xKTAnBgNVBAsTIFN0YXJ0Q29tIENlcnRpZmljYXRpb24g
QXV0aG9yaXR5MSMwIQYDVQQDExpTdGFydENvbSBDbGFzcyAxIENsaWVudCBD
QTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL192vfDon2D9luC
/dtbX64eG3XAtRmvmCSsu1d52DXsCR58zJQbCtB2/A5uFqNxWacpXGGtTCRk
9dEDBlmixEd8QiLkUfvHpJX/xKnmVkS6Iye8wUbYzMsDzgnpazlPg19dnSqf
hM+Cevdfa89VLnUztRr2cgmCfyO9Otrh7LJDPG+4D8ZnAqDtVB8MKYJL6QgK
yVhhaBc4y3bGWxKyXEtx7QIZZGxPwSkzK3WIN+VKNdkiwTubW5PIdopmykwv
IjLPqbJK7yPwFZYekKE015OsW6FV+s4DIM8UlVS8pkIsoGGJtMuWjLL4tq2h
YQuuN0jhrxK1ljz50hH23gA9cbMCAwEAAaOCAWQwggFgMA4GA1UdDwEB/wQE
AwIBBjAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwQwEgYDVR0TAQH/
BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRwOi8vY3JsLnN0YXJ0
c3NsLmNvbS9zZnNjYS5jcmwwZgYIKwYBBQUHAQEEWjBYMCQGCCsGAQUFBzAB
hhhodHRwOi8vb2NzcC5zdGFydHNzbC5jb20wMAYIKwYBBQUHMAKGJGh0dHA6
Ly9haWEuc3RhcnRzc2wuY29tL2NlcnRzL2NhLmNydDAdBgNVHQ4EFgQUJIFs
OWG+SQ+PtxtGK8kotSdIbWgwHwYDVR0jBBgwFoAUTgvvGqRAW6UXaYcwyjRo
Q9BBrvIwPwYDVR0gBDgwNjA0BgRVHSAAMCwwKgYIKwYBBQUHAgEWHmh0dHA6
Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeTANBgkqhkiG9w0BAQsFAAOCAgEA
i+P3h+wBi4StDwECW5zhIycjBL008HACblIf26HY0JdOruKbrWDsXUsiI0j/
7Crft9S5oxvPiDtVqspBOB/y5uzSns1lZwh7sG96bYBZpcGzGxpFNjDmQbcM
3yl3WFIRS4WhNrsOY14V7y2IrUGsvetsD+bjyOngCIVeC/GmsmtbuLOzJ606
tEc9uRbhjTu/b0x2Fo+/e7UkQvKzNeo7OMhijixaULyINBfCBJb+e29bLafg
u6JqjOUJ9eXXj20p6q/CW+uVrZiSW57+q5an2P2i7hP85jQJcy5j4HzA0rSi
F3YPhKGAWUxKPMAVGgcYoXzWydOvZ3UDsTDTagXpRDIKQLZo02wrlxY6iMFq
vlzsemVf1odhQJmi7Eh5TbxI40kDGcBOBHhwnaOumZhLP+SWJQnjpLpSlUOj
95uf1zo9oz9e0NgIJoz/tdfrBzez76xtDsK0KfUDHt1/q59BvDI7RX6gVr0f
QoCyMczNzCTcRXYHY0tq2J0oT+bsb6sH2b4WVWAiJKnSYaWDjdA70qHX4mq9
MIjO/ZskmSY8wtAk24orAc0vwXgYanqNsBX5Yv4sN4Z9VyrwMdLcusP7HJgR
dAGKpkR2I9U4zEsNJQJewM7S4Jalo1DyPrLpL2nTET8ZrSl5Utp1UeGp/2de
oprGevfnxWB+vHNQiu85o6MxggPMMIIDyAIBATCBiTB1MQswCQYDVQQGEwJJ
TDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjEpMCcGA1UECxMgU3RhcnRDb20g
Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIzAhBgNVBAMTGlN0YXJ0Q29tIENs
YXNzIDEgQ2xpZW50IENBAhAwzJDbT70jeYw1Cb83uS/9MA0GCWCGSAFlAwQC
AQUAoIICEzAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJ
BTEPFw0xNjA2MzAyMTI3MjNaMC8GCSqGSIb3DQEJBDEiBCCaZNHKO5ZtI3XD
W+Pd22Vw1wZqzl/ZUDTuW6yiqy9XajBsBgkqhkiG9w0BCQ8xXzBdMAsGCWCG
SAFlAwQBKjALBglghkgBZQMEAQIwCgYIKoZIhvcNAwcwDgYIKoZIhvcNAwIC
AgCAMA0GCCqGSIb3DQMCAgFAMAcGBSsOAwIHMA0GCCqGSIb3DQMCAgEoMIGa
BgkrBgEEAYI3EAQxgYwwgYkwdTELMAkGA1UEBhMCSUwxFjAUBgNVBAoTDVN0
YXJ0Q29tIEx0ZC4xKTAnBgNVBAsTIFN0YXJ0Q29tIENlcnRpZmljYXRpb24g
QXV0aG9yaXR5MSMwIQYDVQQDExpTdGFydENvbSBDbGFzcyAxIENsaWVudCBD
QQIQMMyQ20+9I3mMNQm/N7kv/TCBnAYLKoZIhvcNAQkQAgsxgYyggYkwdTEL
MAkGA1UEBhMCSUwxFjAUBgNVBAoTDVN0YXJ0Q29tIEx0ZC4xKTAnBgNVBAsT
IFN0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSMwIQYDVQQDExpT
dGFydENvbSBDbGFzcyAxIENsaWVudCBDQQIQMMyQ20+9I3mMNQm/N7kv/TAN
BgkqhkiG9w0BAQEFAASCAQAjZrFlcDmKXJIDgYs9abIRm7h2wpYrt5VTFQVt
wgZ56G7dxvXqo4MdeQErCWzMBr9Wd5Po+op4TwrQ0LX4xUT1SpNXMmkLWT88
8ty5kTOAIMxwwwQosBKN3udD4MQ3F6M09QA+b9/pgjy4WPyUeuaH9a4mU4Xx
r9ROwXPjPHJbCiBDAv6F8fs5HkUtanTX8cdBcRkFjTOYxK2hhoKZfDYBbxoh
bwlBRdaZtkCNLy+OHwvYYot6KRIameRYdNF9BbfsoSgInXTF6OTFwfRJUe7q
/3s9hATOAUvYnCdIGNp5FKZ6uOPYSoZ9iC60RselCGqOdU54ujp6148fA4bJ
9o1pAAAAAAAA

--------------ms010202040100050508010908--

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019