diff --git a/mirai-core/src/commonMain/kotlin/MiraiImpl.kt b/mirai-core/src/commonMain/kotlin/MiraiImpl.kt
index 541776e8a..a0f259eb5 100644
--- a/mirai-core/src/commonMain/kotlin/MiraiImpl.kt
+++ b/mirai-core/src/commonMain/kotlin/MiraiImpl.kt
@@ -371,6 +371,15 @@ internal open class MiraiImpl : IMirai, LowLevelApiAccessor {
                     break
                 }
             }
+            bot.network.run {
+                val resp =
+                    TroopManagement.GetAdmin(bot.client, groupCode).sendAndExpect<TroopManagement.GetAdmin.Response>()
+                check(resp is TroopManagement.GetAdmin.Response.Success) { "Failed to get admin info" }
+                sequence.filter { member -> member.permission == MemberPermission.MEMBER && resp.memberList.any { member.uin == it.memberUin } }
+                    .forEach { memberInfoImpl ->
+                        memberInfoImpl.permission = MemberPermission.ADMINISTRATOR
+                    }
+            }
             return sequence
         }
 
diff --git a/mirai-core/src/commonMain/kotlin/contact/info/MemberInfoImpl.kt b/mirai-core/src/commonMain/kotlin/contact/info/MemberInfoImpl.kt
index 3c653670f..809b37d02 100644
--- a/mirai-core/src/commonMain/kotlin/contact/info/MemberInfoImpl.kt
+++ b/mirai-core/src/commonMain/kotlin/contact/info/MemberInfoImpl.kt
@@ -37,9 +37,10 @@ internal data class MemberInfoImpl(
     ) : this(
         uin = jceInfo.memberUin,
         nick = jceInfo.nick,
-        permission = when {
-            jceInfo.memberUin == groupOwnerId -> MemberPermission.OWNER
-            jceInfo.dwFlag == 1L -> MemberPermission.ADMINISTRATOR
+        // 管理员将在 MiraiImpl.kt:359
+        // TroopManagement.GetAdmin 处理
+        permission = when (jceInfo.memberUin) {
+            groupOwnerId -> MemberPermission.OWNER
             else -> MemberPermission.MEMBER
         },
         remark = jceInfo.autoRemark.orEmpty(),
diff --git a/mirai-core/src/commonMain/kotlin/network/protocol/data/proto/OIDB.kt b/mirai-core/src/commonMain/kotlin/network/protocol/data/proto/OIDB.kt
index b5c0d241d..cabc87e17 100644
--- a/mirai-core/src/commonMain/kotlin/network/protocol/data/proto/OIDB.kt
+++ b/mirai-core/src/commonMain/kotlin/network/protocol/data/proto/OIDB.kt
@@ -482,6 +482,61 @@ internal class Oidb0x88d : ProtoBuf {
     ) : ProtoBuf
 }
 
+internal class Oidb0x899 : ProtoBuf {
+    @Serializable
+    internal class ReqBody(
+        @JvmField @ProtoNumber(1) val groupCode: Long = 0L,
+        @JvmField @ProtoNumber(2) val startUin: Long = 0L,
+        @JvmField @ProtoNumber(3) val identifyFlag: Int = 0,
+        @JvmField @ProtoNumber(4) val uinList: List<Long> = emptyList(),
+        @JvmField @ProtoNumber(5) val memberListOpt: MemberList? = null,
+        @JvmField @ProtoNumber(6) val memberNum: Int = 0,
+        @JvmField @ProtoNumber(7) val filterMethod: Int = 0,
+        @JvmField @ProtoNumber(8) val onlineFlag: Int = 0
+    ) : ProtoBuf
+
+    @Serializable
+    internal class RspBody(
+        @JvmField @ProtoNumber(1) val groupCode: Long = 0L,
+        @JvmField @ProtoNumber(2) val startUin: Long = 0L,
+        @JvmField @ProtoNumber(3) val identifyFlag: Int = 0,
+        @JvmField @ProtoNumber(4) val memberList: List<MemberList> = emptyList(),
+        @JvmField @ProtoNumber(5) val errorInfo: ByteArray = EMPTY_BYTE_ARRAY
+    ) : ProtoBuf
+
+    @Serializable
+    internal class MemberList(
+        @JvmField @ProtoNumber(1) val memberUin: Long = 0L,
+        @JvmField @ProtoNumber(2) val uinFlag: Int = 0,
+        @JvmField @ProtoNumber(3) val uinFlagExt: Int = 0,
+        @JvmField @ProtoNumber(4) val uinMobileFlag: Int = 0,
+        @JvmField @ProtoNumber(5) val uinArchFlag: Int = 0,
+        @JvmField @ProtoNumber(6) val joinTime: Int = 0,
+        @JvmField @ProtoNumber(7) val oldMsgSeq: Int = 0,
+        @JvmField @ProtoNumber(8) val newMsgSeq: Int = 0,
+        @JvmField @ProtoNumber(9) val lastSpeakTime: Int = 0,
+        @JvmField @ProtoNumber(10) val level: Int = 0,
+        @JvmField @ProtoNumber(11) val point: Int = 0,
+        @JvmField @ProtoNumber(12) val muteTimestamp: Int = 0,
+        @JvmField @ProtoNumber(13) val flagExt2: Int = 0,
+        @JvmField @ProtoNumber(14) val specialTitle: ByteArray = EMPTY_BYTE_ARRAY,
+        @JvmField @ProtoNumber(15) val specialTitleExpireTime: Int = 0,
+        @JvmField @ProtoNumber(16) val activeDay: Int = 0,
+        @JvmField @ProtoNumber(17) val uinKey: ByteArray = EMPTY_BYTE_ARRAY,
+        @JvmField @ProtoNumber(18) val privilege: Int = 0,
+        @JvmField @ProtoNumber(19) val richInfo: ByteArray = EMPTY_BYTE_ARRAY
+    ) : ProtoBuf
+
+    @Serializable
+    internal class UinKey(
+        @JvmField @ProtoNumber(1) val groupCode: Long = 0L,
+        @JvmField @ProtoNumber(2) val memberUin: Long = 0L,
+        @JvmField @ProtoNumber(3) val genTime: Long = 0L,
+        @JvmField @ProtoNumber(4) val validTime: Int = 0,
+        @JvmField @ProtoNumber(5) val randNum: Int = 0
+    ) : ProtoBuf
+}
+
 @Serializable
 internal class Oidb0x89a : ProtoBuf {
     @Serializable
diff --git a/mirai-core/src/commonMain/kotlin/network/protocol/packet/PacketFactory.kt b/mirai-core/src/commonMain/kotlin/network/protocol/packet/PacketFactory.kt
index f21ae7d84..66d28fe9d 100644
--- a/mirai-core/src/commonMain/kotlin/network/protocol/packet/PacketFactory.kt
+++ b/mirai-core/src/commonMain/kotlin/network/protocol/packet/PacketFactory.kt
@@ -149,6 +149,7 @@ internal object KnownPacketFactories {
         TroopManagement.GroupOperation,
         TroopManagement.GetTroopConfig,
         TroopManagement.ModifyAdmin,
+        TroopManagement.GetAdmin,
         //  TroopManagement.GetGroupInfo,
         TroopManagement.EditGroupNametag,
         TroopManagement.Kick,
diff --git a/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/TroopManagement.kt b/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/TroopManagement.kt
index ebe0b279f..c43b671e9 100644
--- a/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/TroopManagement.kt
+++ b/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/TroopManagement.kt
@@ -30,6 +30,7 @@ import net.mamoe.mirai.internal.utils.io.serialization.*
 import net.mamoe.mirai.utils.daysToSeconds
 
 internal class TroopManagement {
+
     internal object Mute : OutgoingPacketFactory<Mute.Response>("OidbSvc.0x570_8") {
         override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): Response {
             //屁用没有
@@ -67,7 +68,6 @@ internal class TroopManagement {
         }
     }
 
-
     internal object GetGroupInfo : OutgoingPacketFactory<GroupInfoImpl>("OidbSvc.0x88d_7") {
         @Deprecated("")
         operator fun invoke(
@@ -419,4 +419,52 @@ internal class TroopManagement {
         }
 
     }
-}
\ No newline at end of file
+
+    internal object GetAdmin : OutgoingPacketFactory<GetAdmin.Response>("OidbSvc.0x899_9") {
+        operator fun invoke(
+            client: QQAndroidClient,
+            groupCode: Long
+        ): OutgoingPacket = buildOutgoingUniPacket(client) {
+            writeProtoBuf(
+                OidbSso.OIDBSSOPkg.serializer(),
+                OidbSso.OIDBSSOPkg(
+                    command = 2201,
+                    serviceType = 1,
+                    result = 0,
+                    bodybuffer = Oidb0x899.ReqBody(
+                        identifyFlag = 2,
+                        groupCode = groupCode,
+                        startUin = 0,
+                        memberListOpt = Oidb0x899.MemberList(
+                            memberUin = 0,
+                            privilege = 1
+                        )
+                    ).toByteArray(Oidb0x899.ReqBody.serializer())
+                )
+            )
+        }
+
+        override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): Response {
+            return readProtoBuf(OidbSso.OIDBSSOPkg.serializer()).let { oidbssoPkg ->
+                if (oidbssoPkg.result == 0) {
+                    oidbssoPkg.bodybuffer.loadAs(Oidb0x899.RspBody.serializer()).let { resp ->
+                        Response.Success(resp.memberList)
+                    }
+                } else {
+                    Response.Failed(oidbssoPkg.result, oidbssoPkg.errorMsg)
+                }
+            }
+
+        }
+
+        sealed class Response : Packet {
+            class Failed(val code: Int, val msg: String) : Response() {
+                override fun toString(): String = "GetAdmin.Response.Failed(code=$code, msg=$msg)"
+            }
+
+            class Success(val memberList: List<Oidb0x899.MemberList>) : Response() {
+                override fun toString(): String = "GetAdmin.Response.Success"
+            }
+        }
+    }
+}