今日はMicrosoftのセキュリティアップデートの日です。
2023 年 3 月のセキュリティ更新プログラム - リリース ノート - セキュリティ更新プログラム ガイド - Microsoft
2023 年 3 月のセキュリティ更新プログラム (月例) | MSRC Blog | Microsoft Security Response Center
2023年3月15日
2023年3月9日
2023年3月1日
2023/03開催のセミナー
- Web Seminar
- 2023/03/01 01:00-02:00(JST) See What's New in RAD Studio 11.3 Alexandria
- 2023/03/10 01:00-02:00(JST) Q&A Round Table: RAD Studio 11.3 Release
- 2023/03/28 17:00-17:45(JST) 「RAD Studio 11.3 深堀情報!今月はLANSA TV同時配信で」- エンバカデロ・デベロッパーTV(2023年3月)
- Live Seminar
- Community Event
2023年2月28日
RAD Studio/Delphi/C++Builder 11 Alexandria Release 3 (11.3)
RAD Studio/Delphi/C++Builder 11 AlexandriaのRelease 3 (11.3)がリリースされています。インストールには有効なUpdate Subscriptionが必要です。Registered Products Portalからダウンロードできます。
RAD Studio, Delphi, C++Builder 11.3 ISO
RAD Studio, Delphi, C++Builder 11.3 Web Install
RAD Studio, Delphi, C++Builder 11.3 ISO (inline)
RAD Studio, Delphi, C++Builder 11.3 Web Install (Inline)
RAD Studio, Delphi, C++Builder 11.3 ISO (2024 rebuild)
RAD Studio, Delphi, C++Builder 11.3 Web Install (2024 rebuild)
11 Alexandria - Release 3
New features and customer reported issues fixed in RAD Studio 11.3
List of publicly reported bugs fixed in 11.3
RAD Studio 11.3 Alexandria リリースのお知らせ (en)
RAD Studio 11.3へアップデートを行う際のご注意
11.3の新機能: TControlListコントロールで複数アイテムが選択可能に! (en)
RAD Studio 11.3 新機能ウェビナー(日本語吹替版)Part 1 - YouTube
RAD Studio 11.3 新機能ウェビナー(日本語吹替版)Part 2 - YouTube
RAD Studio 11.3 新機能ウェビナー(日本語吹替版)Part 3 - YouTube
2023/04/27追記: インストーラがPatch 1を含むものに差し替えられました。
新しいRAD Studio 11.3 Inline Buildのご案内 (en)
2024/02/21追記: GetItサーバの更新に伴ってインストーラが更新されました。
GetItアップデート: RAD Studio 11のGetItオンラインインストール、DelphiおよびC++Builder Community Editionが利用可能に! (en)
RAD Studio, Delphi, C++Builder 11.3 Web Install (2024 rebuild)
11 Alexandria - Release 3
New features and customer reported issues fixed in RAD Studio 11.3
List of publicly reported bugs fixed in 11.3
RAD Studio 11.3 Alexandria リリースのお知らせ (en)
RAD Studio 11.3へアップデートを行う際のご注意
11.3の新機能: TControlListコントロールで複数アイテムが選択可能に! (en)
RAD Studio 11.3 新機能ウェビナー(日本語吹替版)Part 1 - YouTube
RAD Studio 11.3 新機能ウェビナー(日本語吹替版)Part 2 - YouTube
RAD Studio 11.3 新機能ウェビナー(日本語吹替版)Part 3 - YouTube
2023/04/27追記: インストーラがPatch 1を含むものに差し替えられました。
新しいRAD Studio 11.3 Inline Buildのご案内 (en)
2024/02/21追記: GetItサーバの更新に伴ってインストーラが更新されました。
GetItアップデート: RAD Studio 11のGetItオンラインインストール、DelphiおよびC++Builder Community Editionが利用可能に! (en)
2023年2月27日
[書籍]データベース速攻入門
紀伊國屋書店新宿本店で
データベース速攻入門 (Amazon)/堀内康夫、徳尾秀敬、とみたまさひろ、株式会社リブセンス、村田太、成田優隆、福本誠、大津桜子、藤本正比古、廣山豊、吉村守、杉江伸祐、杉山ジョージ、中村昌登著/技術評論社/ISBN 978-4-297-13362-7/2,420円
を購入。
データベース速攻入門 (Amazon)/堀内康夫、徳尾秀敬、とみたまさひろ、株式会社リブセンス、村田太、成田優隆、福本誠、大津桜子、藤本正比古、廣山豊、吉村守、杉江伸祐、杉山ジョージ、中村昌登著/技術評論社/ISBN 978-4-297-13362-7/2,420円
を購入。
[書籍]プログラマー脳
紀伊國屋書店新宿本店でThe Programmer's Brain (Amazon US)の翻訳である
プログラマー脳 (Amazon)/Felienne Hermans著/水野貴明訳/水野いずみ監訳/秀和システム/ISBN 9784798068534/3,300円
を購入。
プログラマー脳 (Amazon)/Felienne Hermans著/水野貴明訳/水野いずみ監訳/秀和システム/ISBN 9784798068534/3,300円
を購入。
2023年2月15日
2023年2月13日
[書籍]C#クックブック
紀伊國屋書店新宿本店でC# Cookbook (Amazon US)の翻訳である
C#クックブック (Amazon)/ Joe Mayo著/鈴木幸敏訳/オライリー・ジャパン/ISBN 978-4-8144-0018-8/3,960円
を購入。
C#クックブック (Amazon)/ Joe Mayo著/鈴木幸敏訳/オライリー・ジャパン/ISBN 978-4-8144-0018-8/3,960円
を購入。
2023年2月1日
[書籍]Good Code, Bad Code
紀伊國屋書店新宿本店でGood Code, Bad Code (Amazon US)の翻訳である
Good Code, Bad Code (Amazon)/Tom Long著/秋勇紀、高田新山訳/山本大祐監訳/秀和システム/ISBN 9784798068169/3,960円
を購入。
Good Code, Bad Code (Amazon)/Tom Long著/秋勇紀、高田新山訳/山本大祐監訳/秀和システム/ISBN 9784798068169/3,960円
を購入。
2023/02開催のセミナー
- Web Seminar
- 2023/02/14 08:50-16:00(CST) DelphiCon 2023 Day 1
- 2023/02/15 08:50-17:00(CST) DelphiCon 2023 Day 2
- 2023/02/16 08:50-16:00(CST) DelphiCon 2023 Day 3
- 2023/02/28 17:00-17:45(JST) 「Delphi 28回目のバースディ」 - エンバカデロ・デベロッパーTV(2023年2月)
- Live Seminar
- Community Event
2023年1月29日
[書籍][ebook]プログラマーのためのCPU入門
ラムダノートで
プログラマーのためのCPU入門 (Amazon)/Takenobu Tani著/ラムダノート/ISBN 978-4-908686-16-0/3,740円(紙書籍+電子書籍(PDF))、3,520円(電子書籍(PDF)のみ)
を購入して、書籍版が配送されてきました。
プログラマーのためのCPU入門 (Amazon)/Takenobu Tani著/ラムダノート/ISBN 978-4-908686-16-0/3,740円(紙書籍+電子書籍(PDF))、3,520円(電子書籍(PDF)のみ)
を購入して、書籍版が配送されてきました。
2023年1月11日
2023年1月1日
2023/01開催のセミナー
- Web Seminar
- 2023/01/31 17:00-17:45(JST) 「Delphiの関数構文を極めよう」 - エンバカデロ・デベロッパーTV(2023年1月)
- Live Seminar
- Community Event
2022年12月22日
ユーザを偽装してSYSTEMサービスからネットワークリソースにアクセスする
このアーティクルはDelphi Advent Calendar 2022の22日目の記事です(20日ぶり8回目)。
以前WNetAddConnection2を使って他のPCのネットワーク共有にアクセスする方法について書きましたが、これをサービスから実行するとWNetAddConnection2が時々エラー1312(ERROR_NO_SUCH_LOGON_SESSION)になる、という現象が発生します。調べてみたところ、サービスの場合はSystemではなくNetworkServiceで動作していないとこのような状態になるようです(常にエラーになるわけではなく、成功したりエラーになったりという感じ)。もちろんサービスをNetworkServiceで実行すればネットワークアクセスでエラーになることはないのですが、ローカルコンピュータに対するアクセスがUsersグループ相当に制限されてしまいます(サービスで使用する(Local)System/LocalService/NetworkServiceアカウントについてはWindowsテクニカルドキュメント(旧MSDN)のService User Accounts、LocalService Account、NetworkService Account、LocalSystem Accountや@ITのWindowsのサービスで使用される「System」「Local Service」「Network Service」アカウントとは?:Tech TIPSを参照)。
そこでSystemアカウントで動作するサービスから実行することを前提に、ネットワークリソースにアクセスするときだけNetworkServiceアカウントに偽装するようにしてみます。
まずLogonUserでNetworkServiceとしてログインし、返されたトークンハンドルでImpersonateLoggedOnUserを呼び出すことでユーザを偽装します。
切断するときはまずWNetCancelConnection2を呼び出した後で、RevertToSelfで偽装を解除し、CloseHandleでトークンハンドルをクローズすることでログオフします。
以前WNetAddConnection2を使って他のPCのネットワーク共有にアクセスする方法について書きましたが、これをサービスから実行するとWNetAddConnection2が時々エラー1312(ERROR_NO_SUCH_LOGON_SESSION)になる、という現象が発生します。調べてみたところ、サービスの場合はSystemではなくNetworkServiceで動作していないとこのような状態になるようです(常にエラーになるわけではなく、成功したりエラーになったりという感じ)。もちろんサービスをNetworkServiceで実行すればネットワークアクセスでエラーになることはないのですが、ローカルコンピュータに対するアクセスがUsersグループ相当に制限されてしまいます(サービスで使用する(Local)System/LocalService/NetworkServiceアカウントについてはWindowsテクニカルドキュメント(旧MSDN)のService User Accounts、LocalService Account、NetworkService Account、LocalSystem Accountや@ITのWindowsのサービスで使用される「System」「Local Service」「Network Service」アカウントとは?:Tech TIPSを参照)。
そこでSystemアカウントで動作するサービスから実行することを前提に、ネットワークリソースにアクセスするときだけNetworkServiceアカウントに偽装するようにしてみます。
まずLogonUserでNetworkServiceとしてログインし、返されたトークンハンドルでImpersonateLoggedOnUserを呼び出すことでユーザを偽装します。
const
LOGON32_LOGON_NEW_CREDENTIALS = 9;
{$EXTERNALSYM LOGON32_LOGON_NEW_CREDENTIALS}
var
LogonUserUser: String;
LogonUserDomain: String;
LogonUserLogonType: DWORD;
LogonUserLogonProvider: DWORD;
hToken: THandle;
begin
{ Logon as 'NetworkService' user }
LogonUserUser := 'NetworkService';
LogonUserDomain := 'NT AUTHORITY';
LogonUserLogonType := LOGON32_LOGON_NEW_CREDENTIALS;
LogonUserLogonProvider := LOGON32_PROVIDER_DEFAULT;
if LogonUser(PChar(LogonUserUser),PChar(LogonUserDomain),nil,
LogonUserLogonType,LogonUserLogonProvider,hToken) = False then
begin
RaiseLastOSError;
end;
{ Impersonate }
if ImpersonateLoggedOnUser(hToken) = False then
begin
RaiseLastOSError;
end;
これでこの後WNetAddConnection2で接続を試みるときにSystemアカウントではなくNetworkServiceアカウントであるかのように扱われます。切断するときはまずWNetCancelConnection2を呼び出した後で、RevertToSelfで偽装を解除し、CloseHandleでトークンハンドルをクローズすることでログオフします。
{ Revert impersonation }
if RevertToSelf() = False then
begin
RaiseLastOSError;
end;
{ Loggoff }
CloseHandle(hToken);
hToken := INVALID_HANDLE_VALUE;
なおプロセス上で複数のスレッドが動作している場合(特にサービス)など、同一の共有リソース('\\<computername>\<sharename>')に対してWNetAddConnection2をネストして呼び出すとERROR_ALREADY_ASSIGNEDでエラーになります。これを防ぐには同一の共有リソースに対してWNetAddConnection2/WNetCancelConnection2が1回ずつ呼び出されるように、接続している共有リソースをプロセス全体で適切に管理する必要もあります。
2022年12月14日
2022年12月5日
2022年12月2日
InterBase 2020 Update 4
InterBase 2020 Update 4がリリースされています。バージョンは14.4.0.804となっています。
InterBase 2020U4 リリースノート - InterBase (en)
InterBase 2020 Update 4 の新機能 - InterBase (en)
Resolved Defects - InterBase (en)
Embarcadero InterBase 2020 Update 4 のリリース (en)
InterBase 2020U4 リリースノート - InterBase (en)
InterBase 2020 Update 4 の新機能 - InterBase (en)
Resolved Defects - InterBase (en)
Embarcadero InterBase 2020 Update 4 のリリース (en)
レコード型のフィールドのオフセットを取得する
このアーティクルはDelphi Advent Calendar 2022の2日目の記事です(3年ぶり7回目)。
Delphiのレコード型(Cの構造体に相当)は、スタックに配置することができるということ以外にも、特定のメモリレイアウトを定義することができることから、固定長ファイルや指定されたメモリ上のデータを解釈するために使われることがあります。このような場合に、定義したレコード型の特定のフィールドのオフセットが(主にデバッグ用に)欲しくなったりするのですが、Delphiには(
delphi - Get Position of a struct var AKA Offset of record field - Stack Overflow
Delphi: Offset of record field - Stack Overflow
ではちょっと試してみましょう。まずレコード型とそのポインタ型を定義します。
しかし最初に書いたように、特定の(外部で規定された)メモリレイアウトに簡単にアクセスできるようにするためにレコード型を使用する、という目的を考えると、レコード型には
逆アセンブルを見ると、コンパイラは各メンバのオフセットを知ってて
ところで、
このようなことから、レコード型を使用するときは、
なお
Delphiのレコード型(Cの構造体に相当)は、スタックに配置することができるということ以外にも、特定のメモリレイアウトを定義することができることから、固定長ファイルや指定されたメモリ上のデータを解釈するために使われることがあります。このような場合に、定義したレコード型の特定のフィールドのオフセットが(主にデバッグ用に)欲しくなったりするのですが、Delphiには(
SizeOfはあるのに)C/C++のoffsetofマクロ(stddef.h)のようなものが存在しません(RSP-39559)。そこで軽く検索してみたところStack Overflowにそのものずばりな投稿がありました。delphi - Get Position of a struct var AKA Offset of record field - Stack Overflow
Delphi: Offset of record field - Stack Overflow
ではちょっと試してみましょう。まずレコード型とそのポインタ型を定義します。
type
TFoo1 = record
Bar: Boolean;
Baz: Double;
Qux: array [0..8] of Byte;
Quux: Integer;
end;
PFoo1 = ^TFoo1;
これでprocedure TForm1.Button1Click(Sender: TObject);
begin
Memo1.Lines.Add(Format('TFoo1: SizeOf=%d',[SizeOf(TFoo1)]));
Memo1.Lines.Add(Format('TFoo1.Bar: offset=%d',[NativeUInt(@(PFoo1(nil)^.Bar))]));
Memo1.Lines.Add(Format('TFoo1.Baz: offset=%d',[NativeUInt(@(PFoo1(nil)^.Baz))]));
Memo1.Lines.Add(Format('TFoo1.Qux: offset=%d',[NativeUInt(@(PFoo1(nil)^.Qux))]));
Memo1.Lines.Add(Format('TFoo1.Quux: offset=%d',[NativeUInt(@(PFoo1(nil)^.Quux))]));
end;
のように、nilをレコード型へのポインタにキャスト→フィールドを参照→そのアドレスを取得→整数に変換とすることで、そのフィールドのオフセット値を取得できます(アドレスと同じサイズの符号なし整数はNativeUInt型)。では実行してみましょう。TFoo1: SizeOf=32
TFoo1.Bar: offset=0
TFoo1.Baz: offset=8
TFoo1.Qux: offset=16
TFoo1.Quux: offset=28
Delphiのレコード型のデフォルトのアライメントマスクに従って配置されていることがわかります(TFoo1.QuuxのオフセットがDelphiのデフォルトのフィールドのアライメント(構造体アライメント)の8バイトに従った32ではなく、型(Integer)のサイズである4バイトで28になっていることに注意)。しかし最初に書いたように、特定の(外部で規定された)メモリレイアウトに簡単にアクセスできるようにするためにレコード型を使用する、という目的を考えると、レコード型には
packedを指定して、明示的にパディングするような場合が多いと思われます。ではレコード型をpacked recordにしてみましょう。type
TFoo2 = packed record
Bar: Boolean;
Baz: Double;
Qux: array [0..8] of Byte;
Quux: Integer;
end;
PFoo2 = ^TFoo2;
procedure TForm1.Button2Click(Sender: TObject);
begin
Memo1.Lines.Add(Format('TFoo2: SizeOf=%d',[SizeOf(TFoo2)]));
Memo1.Lines.Add(Format('TFoo2.Bar: offset=%d',[NativeUInt(@(PFoo2(nil)^.Bar))]));
Memo1.Lines.Add(Format('TFoo2.Baz: offset=%d',[NativeUInt(@(PFoo2(nil)^.Baz))]));
Memo1.Lines.Add(Format('TFoo2.Qux: offset=%d',[NativeUInt(@(PFoo2(nil)^.Qux))]));
Memo1.Lines.Add(Format('TFoo2.Quux: offset=%d',[NativeUInt(@(PFoo2(nil)^.Quux))]));
end;
実行してみます。TFoo2: SizeOf=22
TFoo2.Bar: offset=0
TFoo2.Baz: offset=1
TFoo2.Qux: offset=9
TFoo2.Quux: offset=18
意図通り、すべてのフィールドがパディングされることなく並んでいることがわかります。逆アセンブルを見ると、コンパイラは各メンバのオフセットを知ってて
nil(=0)に加算しているので、最初からこれをもらう方法があれば…とは思います。また上記のStack Overflowの2番目の投稿にはRTTIを使った方法も紹介されていますが、RTTIのテーブルでループを回しながら文字列の比較をする必要があるため、それに比べればnilを使った方法のほうが優れていると考えられます。ところで、
packedを指定せずデフォルトのアライメントマスクに従って配置された場合、順序型はそのサイズでアライメントされる、との記述があります。つまりtype
TFoo3 = record
Bar: array [0..8] of Byte;
Baz: Boolean;
Qux: array [0..8] of Byte;
end;
PFoo3 = ^TFoo3;
のように1バイトアライメントされている配列のフィールドの次に1バイトの順序型のフィールドがあると、デフォルトのアライメントの8バイトに従ったパディングが行われることなく、連続した配置になる、ということになります(逆も同じ)。procedure TForm1.Button3Click(Sender: TObject);
begin
Memo1.Lines.Add(Format('TFoo3: SizeOf=%d',[SizeOf(TFoo3)]));
Memo1.Lines.Add(Format('TFoo3.Bar: offset=%d',[NativeUInt(@(PFoo3(nil)^.Bar))]));
Memo1.Lines.Add(Format('TFoo3.Baz: offset=%d',[NativeUInt(@(PFoo3(nil)^.Baz))]));
Memo1.Lines.Add(Format('TFoo3.Qux: offset=%d',[NativeUInt(@(PFoo3(nil)^.Qux))]));
end;
実行してみると、TFoo3: SizeOf=19
TFoo3.Bar: offset=0
TFoo3.Baz: offset=9
TFoo3.Qux: offset=10
と、確かにその通りになっています。またDelphi 2007までは型仕様が共通のフィールド(A, B: Extended;のように複数のフィールドが","で並べられて同じ型が指定されているフィールド)は暗黙にpackedとなる、という仕様も存在していました(いま知りました)。このようなことから、レコード型を使用するときは、
packedを指定せず完全にコンパイラにお任せにして特定のメモリレイアウトを必要としないようにするか、packedを指定してパディングも明示的に配置して特定のメモリレイアウトになるようにコーディングするか、どちらかにするべきだと考えられます(この結論そのものは当たり前すぎるものですが)。なお
packedを指定してメモリレイアウトを完全に自分で制御する場合など、定義したレコード型が正しいサイズになっているかどうかは{$IF SizeOf(TFoo2) <> 22}
{$MESSAGE ERROR 'SizeOf(TFoo2) is not 22 bytes.'}
{$IFEND}
のようにコンパイル時にチェックすることができます(Delphi 11.2 Alexandriaだとこれを書いた瞬間にLSPで判定が行われるため、{$MESSAGE}の行がエラー表示になるか淡色表示になるかでわかりますが)。
2022年12月1日
2022/12開催のセミナー
- Web Seminar
- 2022/12/27 17:00-17:45(JST) 「年末年始はプログラミングの基礎技術を高めよう!Delphiのストリームを使う」 - エンバカデロ・デベロッパーTV(2022年12月)
- Live Seminar
- Community Event
2022年11月9日
登録:
投稿 (Atom)