Jump to content
Sign in to follow this  
Manko

ProDLLer: Unknown code running? Befriend or Kill!

Recommended Posts

Thanx!

Much appreciated! You're welcome!

/Manko


Yes i rush things! (I sorta do small bursts inbetween doing nothing.) Things I have rushed and reRushed:* ProDLLer - Process manager - Unload viri modules (dll) and moore...* _WinAPI_ProcessListOWNER_WTS() - Get Processes owner list...* _WinAPI_GetCommandLineFromPID() - Get commandline of target process...* _WinAPI_ThreadsnProcesses() Much info if expanded - optional Indented "Parent/Child"-style Processlist. Moore to come... eventually...

Share this post


Link to post
Share on other sites

Hi!

The reason I have not already done that is;

1. People seldom have much trouble with such hooks.

2. Getting the names of those hooks is trickier... They reside in multiple files...

I feel a slight urge to look into this again though... ...but it will not happen in a flash... PM me to keep me on my toes. :graduated:

/Manko


Yes i rush things! (I sorta do small bursts inbetween doing nothing.) Things I have rushed and reRushed:* ProDLLer - Process manager - Unload viri modules (dll) and moore...* _WinAPI_ProcessListOWNER_WTS() - Get Processes owner list...* _WinAPI_GetCommandLineFromPID() - Get commandline of target process...* _WinAPI_ThreadsnProcesses() Much info if expanded - optional Indented "Parent/Child"-style Processlist. Moore to come... eventually...

Share this post


Link to post
Share on other sites

@rchockxm - Here you go!

New version in first post.

; 0.501

; Added: SSDTshadow - not complete, but fully functional. = lacking names. (Logic is painful; need to guard against faults...)

; Fixed: Lockup in crashnet if "Services.exe" and "System" is suspended. Just resume them... You can suspend again...

; Fixed: Further lockups, same, to do with themes and "lsass.exe"...

Need to keep testing in win7/vista... Have to set up systems... later I will work on names... ("Logic" for it is painful and will take some work to get it right...)

/Manko


Yes i rush things! (I sorta do small bursts inbetween doing nothing.) Things I have rushed and reRushed:* ProDLLer - Process manager - Unload viri modules (dll) and moore...* _WinAPI_ProcessListOWNER_WTS() - Get Processes owner list...* _WinAPI_GetCommandLineFromPID() - Get commandline of target process...* _WinAPI_ThreadsnProcesses() Much info if expanded - optional Indented "Parent/Child"-style Processlist. Moore to come... eventually...

Share this post


Link to post
Share on other sites

hI!

New version in first post.

; 0.502

; Fixed: Gui-problem fixed by BeginPaint/endpaint... tested on win7

; Fixed: "Crashnet" and SuspendAll. In the unlikely event that this happens. All procs will be resumed on vist and win7.

; Fixed: Fixed false positives in SSDTshadow on vista/win7.

/Manko


Yes i rush things! (I sorta do small bursts inbetween doing nothing.) Things I have rushed and reRushed:* ProDLLer - Process manager - Unload viri modules (dll) and moore...* _WinAPI_ProcessListOWNER_WTS() - Get Processes owner list...* _WinAPI_GetCommandLineFromPID() - Get commandline of target process...* _WinAPI_ThreadsnProcesses() Much info if expanded - optional Indented "Parent/Child"-style Processlist. Moore to come... eventually...

Share this post


Link to post
Share on other sites

Yeah, minor update, but still atleast a nasty lockup in Vista/7 among them...

; 0.503
; Fixed: Don't leave icon in tray when leaving, XP/7.
; Fixed: Don't leave them after crash either.
; Added: Don't allow shutdown or standby while ProDLLing in XP, Thanks to Prog@ndy. Vista/7, dont alow shutdown.
; Added: Don't let ProDLLer be put to sleep by idletimers in xp/vista/7.
; Fixed: Lockup when returning from sleep in vista/7, . (if "Noprocs" running then disable "noprocs" and resume all procs.)
; Change: No suspending of "theme"-service in XP. On crash, just resume all processes... like we have to in vista/7...

Download in first post.

/Manko


Yes i rush things! (I sorta do small bursts inbetween doing nothing.) Things I have rushed and reRushed:* ProDLLer - Process manager - Unload viri modules (dll) and moore...* _WinAPI_ProcessListOWNER_WTS() - Get Processes owner list...* _WinAPI_GetCommandLineFromPID() - Get commandline of target process...* _WinAPI_ThreadsnProcesses() Much info if expanded - optional Indented "Parent/Child"-style Processlist. Moore to come... eventually...

Share this post


Link to post
Share on other sites

Hi, jamie!

Thanks!

You just sliced my achilles-heel... :graduated:

It would be a LOT of work, porting this to x64...

I program the driver and dll in assembler. They're needed for kernel-stuff and some stuff for threads and for speed...

I use masm32 and am used to it. (Not really fluent, but I get by...) You noticed it's called: Masm32? No real support for 64-bit...

I would have to dig up and learn something new, as well as reprogram a lot of code.

I am heavily engaged in familylife and work and also a little bit lazy... (Me and shortcuts, and whatever...)

I don't own an x64 to help development either...

One other hurdle is x64 and signed drivers...

You can see I'm putting off the inevitable... time will force me to bite the sour apple or I will have to quit that part of my hobbyish relation to computers...

/Manko


Yes i rush things! (I sorta do small bursts inbetween doing nothing.) Things I have rushed and reRushed:* ProDLLer - Process manager - Unload viri modules (dll) and moore...* _WinAPI_ProcessListOWNER_WTS() - Get Processes owner list...* _WinAPI_GetCommandLineFromPID() - Get commandline of target process...* _WinAPI_ThreadsnProcesses() Much info if expanded - optional Indented "Parent/Child"-style Processlist. Moore to come... eventually...

Share this post


Link to post
Share on other sites

Hi, jamie!

Thanks!

You just sliced my achilles-heel... :graduated:

It would be a LOT of work, porting this to x64...

I program the driver and dll in assembler. They're needed for kernel-stuff and some stuff for threads and for speed...

I use masm32 and am used to it. (Not really fluent, but I get by...) You noticed it's called: Masm32? No real support for 64-bit...

I would have to dig up and learn something new, as well as reprogram a lot of code.

I am heavily engaged in familylife and work and also a little bit lazy... (Me and shortcuts, and whatever...)

I don't own an x64 to help development either...

One other hurdle is x64 and signed drivers...

You can see I'm putting off the inevitable... time will force me to bite the sour apple or I will have to quit that part of my hobbyish relation to computers...

/Manko

Lol i didnt mean to go for the kill. Its great work what youve done so far. Its took me a while to start adding x64 bit to my programs but im seeing it more and more now including with my own new laptop.


Drunken Frat-Boy Monkey Garbage

Share this post


Link to post
Share on other sites

If this is just a "hobbyish" kind of thing for you, I'd imagine what you'd be capable of with a stiff level of dedication.

Share this post


Link to post
Share on other sites

Ok, so I had noticed this before but didn't bother to say anything but when I ran the latest version with the latest version of autoit, I get errors about previously declared constants.

Global Const $READ_CONTROL = 0x20000       ; Constant in services.au3 Include
Global Const $READ_CONTROL = 0x00020000    ; Constant in securityconstants.au3 Include

Which ones should I keep and why are they different?

Edited by THAT1ANONYMOUSEDUDE

Share this post


Link to post
Share on other sites

Either one is ok to keep, they're both the same just written differently.

Global Const $READ_CONTROL = 0x20000       ; Constant in services.au3 Include
Global Const $READ_CONTROL1 = 0x00020000    ; Constant in securityconstants.au3 Include
If $READ_CONTROL = $READ_CONTROL1 Then MsgBox(64, "", "They're the same number")

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites

Oh, alright.

To be more precise, these are all the conflicting values.

Global Const $READ_CONTROL = 0x20000
Global Const $WRITE_DAC = 0x40000
Global Const $WRITE_OWNER = 0x80000
Global Const $STANDARD_RIGHTS_REQUIRED = BitOR( $DELETE, _
          $READ_CONTROL, _
          $WRITE_DAC, _
          $WRITE_OWNER )

Share this post


Link to post
Share on other sites

Hi Manko,

this is about Prodller + windows 7.

I am using purge.exe (for flushing the FileSystem Cache) along with Prodller on Win7. and I am getting the error :

OS: Win7

Hardware : 32bit.

Error: Unable to start correctly (0xc00000142). Click OK to close the application

Purge:

Blog Link : http://james-ross.co.uk/weblog/2009/07/29/01

Exe : http://james-ross.co.uk/temp/purge.exe

Source : http://james-ross.co.uk/temp/purge.cpp

 

However, before using ShellExecute / Run , if I use the function "prodstop()" then purge.exe works perfectly well.

Note: I am not facing any issues with the below code when executed on WinXP (32 bit).

#include <Date.au3>
#include <Process.au3>
#include "Services.au3"
#include <security.au3>

Global $hColdBoot = 0
Local $PID
OnAutoItExitRegister("ex")
FileInstall('purge.exe', @WindowsDir & '\purge.exe', 1)
prodservice()
prodstart()
ShellExecute(@WindowsDir & '\purge.exe','', @WindowsDir,'open' ,@SW_HIDE)
Sleep(1000)
ex()

Func ex()
    prodstop()
    DllCall("kernel32.dll", "int", "DeviceIoControl", "dword", $hColdBoot, "dword", 0x00226110, _
            "int*", 0, "dword", 4, "int*", 0, "dword", 0, "dword*", 0, "ptr", 0)
    _Service_Stop("skeleton")
    _Service_Delete("skeleton")
EndFunc ;==>ex

Func prodstart_remote($PID_Local)
    DllCall("kernel32.dll", "int", "DeviceIoControl", "dword", $hColdBoot, "dword", 0x00226110, _
            "int*", 0, "dword", 4, "int*", 0, "dword", 0, "dword*", 0, "ptr", 0)
    DllCall("kernel32.dll", "int", "DeviceIoControl", "dword", $hColdBoot, "dword", 0x00226110, _
            "int*", 1, "dword", 4, "int*", 0, "dword", 0, "dword*", 0, "ptr", 0)
    DllCall("kernel32.dll", "int", "DeviceIoControl", "dword", $hColdBoot, "dword", 0x00226110, _
            "int*", $PID_Local, "dword", 4, "int*", 0, "dword", 0, "dword*", 0, "ptr", 0)
EndFunc ;==>prodstart_remote


Func prodstop()
    DllCall("kernel32.dll", "int", "DeviceIoControl", "dword", $hColdBoot, "dword", 0x00226110, _
            "int*", 0, "dword", 4, "int*", 0, "dword", 0, "dword*", 0, "ptr", 0)
EndFunc ;==>prodstop

Func prodstart()
    DllCall("kernel32.dll", "int", "DeviceIoControl", "dword", $hColdBoot, "dword", 0x00226110, _
            "int*", 1, "dword", 4, "int*", 0, "dword", 0, "dword*", 0, "ptr", 0)

    DllCall("kernel32.dll", "int", "DeviceIoControl", "dword", $hColdBoot, "dword", 0x00226110, _
            "int*", @AutoItPID, "dword", 4, "int*", 0, "dword", 0, "dword*", 0, "ptr", 0)
EndFunc ;==>prodstart


Func prodservice()
    DllCall("ntdll.dll", "int", "RtlAdjustPrivilege", "int", 20, "int", 1, "int", 0, "int*", 0) ; Get SeDebugPrivilege
    FileInstall("skeleton.sys", @TempDir & "\skeleton.sys", 1)
    If FileExists(@TempDir & "\skeleton.sys") Then
        Local $fault = "", $x = 0, $drvpath = @TempDir & "\"
        While 1
            If Not My_Service_Create("skeleton", "Skeleton Driver", $drvpath & "skeleton.sys", $SERVICE_KERNEL_DRIVER, $SERVICE_DEMAND_START, $SERVICE_ERROR_IGNORE, 0) Then
                $fault = @LF & $x & " My_Service_Create: @error=" & @error
            EndIf
            If Not _Service_Start("skeleton") Then
                $fault &= @LF & $x & " _Service_Start: @error=" & @error
                If @error = 3 Then
                    If $x < 2 Then
                        _Service_Stop("skeleton")
                        _Service_Delete("skeleton")
                        FileInstall("skeleton.sys", @TempDir & "\skeleton.sys", 1)
                        $drvpath = @TempDir & "\"
                        $x += 1
                        ContinueLoop
                    EndIf
                EndIf
            EndIf
            _Service_Delete("skeleton")
            $hColdBoot = DllCall("kernel32.dll", "int", "CreateFile", "str", "\\.\skeleton", "dword", 0xc0000000, _
                    "dword", 0, "dword", 0, "dword", 3, "dword", 0, "dword", 0)
            If $hColdBoot[0] = 0 Or $hColdBoot[0] = -1 Then
                Local $ret = _Service_QueryStatus("skeleton")

                If @error Or $ret[1] = $SERVICE_STOPPED Then
                    If $x < 3 Then
                        If $x = 0 Then
                            ; No action. A second try sometimes fixes it...
                        ElseIf $x = 1 Then
                            _Service_Delete("skeleton")
                        ElseIf $x = 2 Then
                            _Service_Delete("skeleton")
                        Else
                            RegDelete("HKLM\SYSTEM\ControlSet001\Services\Skeleton")
                            RegDelete("HKLM\SYSTEM\ControlSet002\Services\Skeleton")
                            RegDelete("HKLM\SYSTEM\ControlSet003\Services\Skeleton")
                            RegDelete("HKLM\SYSTEM\CurrentControlSet\Services\Skeleton")
                        EndIf
                        $x += 1
                        ContinueLoop
                    EndIf
                    MsgBox(0, "Form1", "Couldn't start sys so I can not aquire DRIVER handle!" & $fault)
                    Exit
                Else
                    MsgBox(0, "Form1", "sys is running but I can not aquire DRIVER handle!" & $fault)
                    Exit
                EndIf
            Else
                $hColdBoot = $hColdBoot[0]
                ExitLoop
            EndIf
        WEnd
    Else
        MsgBox(0, "Form1", "File does not exist: sys")
        Exit
    EndIf
    DllCall("kernel32.dll", "int", "DeviceIoControl", "dword", $hColdBoot, "dword", 0x00226110, _
            "int*", 1, "dword", 4, "int*", 0, "dword", 0, "dword*", 0, "ptr", 0)

EndFunc   ;==>prodservice

Func My_Service_Create($sServiceName, _
        $sDisplayName, _
        $sBinaryPath, _
        $nServiceType = 0x00000010, _
        $nStartType = 0x00000002, _
        $nErrorType = 0x00000001, _
        $nDesiredAccess = 0x000f01ff)
    Local $hAdvapi32
    Local $hKernel32
    Local $arRet
    Local $hSC
    Local $lError = -1
    $hAdvapi32 = DllOpen("advapi32.dll")
    If $hAdvapi32 = -1 Then Return 0
    $hKernel32 = DllOpen("kernel32.dll")
    If $hKernel32 = -1 Then Return 0
    $arRet = DllCall($hAdvapi32, "long", "OpenSCManager", _
            "str", ".", _
            "str", "ServicesActive", _
            "long", $SC_MANAGER_ALL_ACCESS)
    If $arRet[0] = 0 Then
        $arRet = DllCall($hKernel32, "long", "GetLastError")
        $lError = $arRet[0]
    Else
        $hSC = $arRet[0]
        $arRet = DllCall($hAdvapi32, "long", "OpenService", _
                "long", $hSC, _
                "str", $sServiceName, _
                "long", $SERVICE_INTERROGATE)
        If $arRet[0] = 0 Then
            $arRet = DllCall($hAdvapi32, "long", "CreateService", _
                    "long", $hSC, _
                    "str", $sServiceName, _
                    "str", $sDisplayName, _
                    "long", $nDesiredAccess, _
                    "long", $nServiceType, _
                    "long", $nStartType, _
                    "long", $nErrorType, _
                    "str", $sBinaryPath, _
                    "int", 0, _
                    "ptr", 0, _
                    "int", 0, _
                    "int", 0, _
                    "int", 0)
            If $arRet[0] = 0 Then
                $arRet = DllCall($hKernel32, "long", "GetLastError")
                $lError = $arRet[0]
            Else
                DllCall($hAdvapi32, "int", "CloseServiceHandle", "long", $arRet[0])
            EndIf
        Else
            DllCall($hAdvapi32, "int", "CloseServiceHandle", "long", $arRet[0])
        EndIf
        DllCall($hAdvapi32, "int", "CloseServiceHandle", "long", $hSC)
    EndIf
    DllClose($hAdvapi32)
    DllClose($hKernel32)
    If $lError <> -1 Then
        SetError($lError)
        Return 0
    EndIf
    Return 1
EndFunc   ;==>My_Service_Create

Thanks again.

regards

Edited by DeltaRocked

Share this post


Link to post
Share on other sites

When i unzip it

My eset anti-virus programs tell me..

It found the virus at skeleton.sys (WIN32/ROOTKIT.AGENT.NXY)

Can you check it ?

Thanks first...


-Everything are starting by the dreams.-Everybody is working with computer.-Everydays will auto because we need it. Come on..Let's doing...AUTOIT....^^"..just a little idea..a little A.D.

Share this post


Link to post
Share on other sites

auto-it-tous,

I get no warnings from AVG. Besides after 9 years as a member here I thought you might have developed a more jaundiced attitude to AV warnings when it has to do with anything AutoIt related. ;)

Anyway, if you do not trust it - do not run it. Simple really. :)

M23


Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By bobflumox
      Hi all,
      My programming knowledge is very basic.
      I have an old script that creates shares and assign permissions. It normally registers SetAcl.ocx if necessary and creates an object to assign permissions.
      The command that registers SetAcl was apparently working fine under Windows 7 but is not working under Windows 10.
      RunWait("regsvr32.exe path\to\setacl.ocx /s", "", @SW_HIDE) As I'm logged in as admin, I changed this command to :
      RunAsWait(@UserName, "", "", 0, "regsvr32.exe path\to\setacl.ocx /s", "", @SW_HIDE) It seems to terminate correctly but the script still doesn't work as expected.
      To check that, I've created that small script :
      Local $objSetAcl = ObjCreate("SETACL.SetACLCtrl.1") If IsObj($objSetAcl) Then ConsoleWrite("Object successfully created." & @CRLF) Else ConsoleWrite("Object not created. Registering SetAcl.ocx" & @CRLF) Local $result = RunAsWait(@UserName, "", "", 0, "regsvr32.exe path\to\setacl.ocx /s", "", @SW_HIDE); Use of my admin username to elevate CMD ConsoleWrite("Return code : " & $result & @CRLF) ConsoleWrite("Creating object" & @CRLF) $objSetAcl = ObjCreate("SETACL.SetACLCtrl.1") If IsObj($objSetAcl) Then ConsoleWrite("Object successfully created." & @CRLF) Else ConsoleWrite("Object creation failed." & @CRLF) EndIf EndIf It tries to register SetAcl.ocx, return code 0 seems to be fine but still can't use SetAcl.
      But if I go to CMD as admin, run the regsvr32 command and restart my script, it can create the object without issue.
      I know my poor knowledge makes me miss something. Anyone can help me figure this out ?
    • By Gowrisankar
      Dear members of the forum,
      I'm working on a project in which I have to use Image recognition technique. 
      Due to client restrictions, I couldn't use AutoIt for this project. 
      Is there a way to use this DLL "ImageSearchDLL.dll" (which is used to do image recognition steps in AutoIt) in VB.Net to achieve the same result? 
      I have used this DLL few years before and got good results. If there is a latest version of this DLL and if you can share it, that will be helpful too.
      Any guidance is deeply appreciated.
    • By DesireDenied
      Hey guys,
      I having some hard times getting false-positive, probably because I am trying to execute my AutoUpdater.
      Here is my code:
       
      Global $iUpdateTimer = 0 While 1 checkUpdates(10) WEnd Func checkUpdates($iDelay = 10) $iDelay = $iDelay * 1000 * 60 If TimerDiff($iUpdateTimer) > $iDelay Then ConsoleWrite('checking for updates...' & @CRLF) $iUpdateTimer = TimerInit() If FileExists('AutoUpdater.exe') Then ShellExecuteWait('AutoUpdater.exe') ; this is the line which cause my problem EndIf EndFunc And AutoUpdater code:
      #include <MsgBoxConstants.au3> #include <FileConstants.au3> Global $sExecName = 'test.exe' Global $sUpdatePath = @UserProfileDir &'\desktop\AnyAppName\update\'& $sExecName Global $sUserPath = @UserProfileDir &'\desktop\AnyAppName\'& $sExecName Global $sCopyright = 'someUniqueStringHere' If Not FileExists($sUpdatePath) Then Exit 0 If FileGetVersion($sUpdatePath, $FV_LEGALCOPYRIGHT) <> $sCopyright Then Exit 0 ; checking if we really want to update and execute the file If FileGetVersion($sUpdatePath) > FileGetVersion($sUserPath) Then $iResponse = MsgBox(BitOR($MB_YESNO, $MB_ICONQUESTION),'AnyAppName', 'There is an update available, would you like to update?') If $iResponse == $IDYES Then If ProcessExists($sExecName) Then ProcessClose($sExecName) Sleep(500) EndIf FileCopy($sUpdatePath, $sUserPath, $FC_OVERWRITE) Sleep(3000) ShellExecute($sUserPath) Exit 1 EndIf EndIf Exit 0 I am not trying to ask, why is my code is getting recognized as false-positive, because this is quite obvious, but is there any other way to get things done without running external process?
       

    • By nacerbaaziz
      hello autoit team
      is there any wey to check if any process run as admin or no?
      i mean e.g if i want to restart any process, now i have the ability to get the process path and commands line
      what i need is a wey to check if the process was runing as admin or no to restart it with the same state.
      here is the part that am using it to restart the process
      func _processRestart($i_pid, $s_ProcessPath) if not (ProcessExists($i_ProcessPid)) then return SetError(1, 0, -1) local $s_ProcessWorkDir = _WinAPI_GetProcessWorkingDirectory($i_ProcessPid) ProcessClose($i_ProcessPid) ProcessWaitClose($i_ProcessPid) ProcessWait(ShellExecute($i_pid,"", $s_ProcessWorkDir)) ProcessesGetList() return true endFunc thanks in advance
×
×
  • Create New...