プロが教えるわが家の防犯対策術!

administratorの権限がないユーザーがadministratorのみ書き込み可能なフォルダにプログラムを通じて書き込みできるシステムを考えています。

アイデアとして作成したプログラムにadministratorで実行することができればうまくいくのではと思い、OSのサービス機能を調査しているところです。
もし経験があるかたがおりましたらお教えください。
またWindows2000でプログラムをサービスに登録する方法も探しています。
宜しくお願いします。

OS:Windows2000+SP2
開発プログラム:VB6.0+SP5

A 回答 (6件)

できました!



STARTUPINFO構造体の定義を

Public Type STARTUPINFO
cb As Long
lpReserved As Long
lpDesktop As Long
lpTitle As Long
dwX As Long
dwY As Long
dwXSize As Long
dwYSize As Long
dwXCountChars As Long
dwYCountChars As Long
dwFillAttribute As Long
dwFlags As Long
wShowWindow As Integer
cbReserved2 As Integer
lpReserved2 As Long
hStdInput As Long
hStdOutput As Long
hStdError As Long
End Type

に変えてください。

イミディエイトウィンドウで

?createprocesswithlogon("名前", "ドメイン", "パスワード","c:\winnt\notepad.exe", vbnullstring, "c:\", 0, 0)

などと入力してEnterをおすと、ユーザー名などが適切な場合、メモ帳がちゃんと起動します。

この関数の注意は、必ず実行時のディレクトリを指定しなければならないということです。
それ以外は、ドメインが省略されていたりしても、ユーザー名とパスワードさえしっかりしていれば、起動できるみたいです。
また、アプリケーション名はフルパスで指定してください。

はぁ、良かった。
原因は、スタートアップ構造体内の文字列でした。
これもUNICODEが原因です。

えっ? Cで?
CはUNICODEも普通に扱えるので簡単に・・・、といいたいところですが、VC++にはどうもCreateProcessWithLogonW関数が定義されていないので、自分で探さなきゃならんみたいですね。

Win32アプリケーションを選択して、単純なアプリケーションを自動で生成。

#include "stdafx.h"

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){

HMODULE hMod = GetModuleHandle("advapi32");

STARTUPINFOW si;
PROCESS_INFORMATION pi;

ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);

//↓ぐちゃぐちゃですが合ってます
BOOL (__stdcall *CreateProcessWithLogonW)(LPCWSTR, LPCWSTR, LPCWSTR, DWORD, LPCWSTR, LPWSTR, DWORD, LPVOID, LPCWSTR, LPSTARTUPINFOW, LPPROCESS_INFORMATION) = (BOOL (__stdcall *)(LPCWSTR, LPCWSTR, LPCWSTR, DWORD, LPCWSTR, LPWSTR, DWORD, LPVOID, LPCWSTR, LPSTARTUPINFOW, LPPROCESS_INFORMATION))GetProcAddress(hMod, "CreateProcessWithLogonW");
if(!CreateProcessWithLogonW){
MessageBox(0, "CreateProcessWithLogonW is not found", 0, 0);
}
CreateProcessWithLogonW(
L"名前",
L"ドメイン",
L"パスワード",
0,
L"c:\\winnt\\notepad.exe",
NULL,
0,
NULL,
NULL,
&si,
&pi
);

FreeLibrary(hMod);

return 0;
}

動作確認済みです。
    • good
    • 0

あっ、追記です。



CreateProcessもWithLogonWもプロセスハンドルとスレッドハンドルを生成します。
これを開放せずに使いまくってると、リソースがつきでしまいます。

Public Declare Function CloseHandle Lib "kernel32" Alias "CloseHandle" (ByVal hObject As Long) As Long

をモジュールの一番上に追加して、

End Functionの直前の行に

CloseHandle PI.hThread
CloseHandle PI.hProcess

を追加してください。
Cのほうも使うんだったら、同様に!

この回答への補足

ありがとうございます。
引数で用いられているcur_dirですが、これはVBで予約語になっているようです。
この変数名を変えて実行しましたらうまくいきました。

補足日時:2002/05/17 15:51
    • good
    • 0
この回答へのお礼

今回の件では大変お世話になりました。
とてもよい刺激になり、開発の励みになりました。
今後も宜しくお願いします

お礼日時:2002/05/17 15:58

CreateProcessなら、advai32じゃなくてkernel32の中にはいっています。


Lib "advapi32" をLib "kernel32" に書き換えるとCreateProcess見つかるでしょうが、多分参考になりません。
CreateProcessWithLogonWにはUNICODE版しか用意されていないので、VBから操作するのは面倒くさいからです。

私も強制終了の原因を調べているところです。

ちなみに、このコードを貼り付けて、モジュール内定義のCreateProcessWithLogonを呼び出したら、強制終了しましたか?
もしかしたら、私のローカルエラーかもしれませんから。

# セキュリティポリシーに、別ユーザーでプロセスを実行するという権限が割り当てられてなかったら、だめだったような・・・。
    • good
    • 0
この回答へのお礼

ありがとうございます。
haporunさんのプログラムをこちらで実行させていただきました。
メモリの読み込みエラーがでてしまいます。
参考までにCで作成したこの関数を公開していただけないでしょうか?
宜しくお願いします

お礼日時:2002/05/17 14:07

ありゃ?


強制終了してしまいました。
原因不明・・・。
原因解明に努めてみます。

基本的にはこれでいいはずなんですが。
    • good
    • 0
この回答へのお礼

ありがととうございます。
無理を言ってすみませんでした。
実は、私もCreateProcessを参考に開発したのですがうまくいきませんでした。
dll内に関数が見つからないというエラーで現在、ストップしています。

お礼日時:2002/05/17 11:19

標準モジュールを作って



Public Const SW_NORMAL = 1

Public Type STARTUPINFO
cb As Long
lpReserved As String
lpDesktop As String
lpTitle As String
dwX As Long
dwY As Long
dwXSize As Long
dwYSize As Long
dwXCountChars As Long
dwYCountChars As Long
dwFillAttribute As Long
dwFlags As Long
wShowWindow As Integer
cbReserved2 As Integer
lpReserved2 As Long
hStdInput As Long
hStdOutput As Long
hStdError As Long
End Type
Public Type PROCESS_INFORMATION
hProcess As Long
hThread As Long
dwProcessId As Long
dwThreadId As Long
End Type

Public Declare Function CreateProcessWithLogonW Lib "advapi32" ( _
lpUserName As Byte, _
lpDomain As Byte, _
lpPassword As Byte, _
ByVal dwLogonFlags As Long, _
lpApplicationName As Byte, _
lpCommandLine As Byte, _
ByVal dwCreationFlags As Long, _
ByVal lpEnvironment As Long, _
lpCurrentDirectory As Byte, _
lpStartupInfo As STARTUPINFO, _
lpProcessInformation As PROCESS_INFORMATION _
) As Long

Public Function CreateProcessWithLogon( _
Username As String, _
Domain As String, _
Pasword As String, _
Appname As String, _
Cmdline As String, _
CurDir As String, _
Optional ByVal LogonFlag As Long, _
Optional ByVal CreateFlag As Long = &H20 _
) As Long

Dim Usr() As Byte, Dom() As Byte, Pas() As Byte
Dim Ap() As Byte, Cmd() As Byte, Cur() As Byte
Dim SI As STARTUPINFO, PI As PROCESS_INFORMATION

SI.cb = Len(SI)

Usr = Username + vbNullChar: Dom = Domain + vbNullChar: Pas = Pasword + vbNullChar
Ap = Appname + vbNullChar: Cmd = Cmdline + vbNullChar: Cur = CurDir + vbNullChar

CreateProcessWithLogon = CreateProcessWithLogonW( _
Usr(0), _
Dom(0), _
Pas(0), _
LogonFlag, _
Ap(0), _
Cmd(0), _
CreateFlag, _
ByVal 0, _
Cur(0), _
SI, _
PI _
)
End Function

これでどうでしょう。
    • good
    • 0

CreateProcessWithLogonW関数を使いませう。


これである特定のプログラムを起動するプログラムを作って、そのプログラムが目的のフォルダに対して操作をします。

注意

○ この関数はパスワードを引数として入れますが、リテラル値でパスワードを書かないように。
なにか暗号化処置を施すべきです。
○ この関数は、たしかAPILOADERに載ってません。
○ この関数はUNICODE版のみなので、文字列をByRef x As Byteで宣言するように。
○ この関数で起動したプログラムが、他の任意のプログラムを起動できないように注意。

参考URL:http://www.microsoft.com/JAPAN/developer/library …

この回答への補足

ありがとうございます。今、参考URLを見ました。
実はAPIについては素人で,この関数の使い方を教えてください。
VBのサンプルプログラムをいただけると幸いです。
宜しくお願いします。

補足日時:2002/05/15 17:27
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!